Assignment 1

416 Distributed Systems: Assignment 1

Due: Jan 15th at 11:59PM

Winter 2018

This assignment is intended to get you started with programming in the Go language. To solve this assignment you will need to install Go, figure out how to compile, run, and debug a Go program, and implement a UDP+TCP-based protocols described below for connecting to two services: a proof of work (PoW) authentication service, and a fortune service. The assignment also has an extra credit component: your solution will compete against other students' solutions in the total time to retrieve and print out the fortune. The top fastest 10 solutions will receive an extra 2% added to their final course grade.

High-level protocol description

There are three kinds of nodes in the system: a client (that you will implement), an authentication server (aserver) to verify a client's submitted PoW, and a fortune server (fserver) that returns a fortune string to the client. You will test and debug your solution against running aserver and fserver instances. However, you will not have access to their code. You are given initial starter code (below) which contains the expected message type declarations. Both aserver and fserver serve multiple clients simultaneously. Each client implements a sequential protocol control flow, interacting with the aserver first, and later with the fserver. The client communicates with aserver over UDP and with the fserver over TCP using JSON messages.

The client is run knowing the UDP IP:port of the aserver. It follows the following steps:

  1. The client sends a UDP message with arbitrary payload to the aserver.
  2. The client receives a NonceMessage reply containing an string nonce from the aserver and N, which determines the difficulty of the PoW procedure.
  3. The client finds an string value of secret such that the MD5 hash of the concat(nonce, secret) value has N zeroes at the end of the hash. The client then sends the secret value it found to the aserver as part of a SecretMessage.
  4. The aserver verifies the client's PoW and replies with a FortuneInfoMessage that contains information for contacting the fserver (its TCP IP:port and an int64 fortune nonce to use when connecting to it).
  5. The client sends a FortuneReqMessage to fserver.
  6. The client receives a FortuneMessage from the fserver. This message contains a fortune string as well as the rank of this solution (relative to all other solutions that have correctly interacted with the aserver and fserver).
  7. The client must print out the received fortune string on a new newline-terminated line and then exit.
The communication steps in this protocol are illustrated in the following space-time diagram:


Protocol corner-cases

  • The aserver will reply with an ErrMessage in case the PoW is invalid.
  • The aserver will reply to all messages that it perceives as not being SecretMessage with a new NonceMessage.
  • The fserver will reply with an ErrMessage in case it cannot unmarshal the message from the client.
  • The fserver will reply with an ErrMessage in case an incorrect fortune nonce is supplied in the FortuneReqMessage.
  • You can assume that all messages fit into 1024 bytes.

Implementation requirements

  • The client code must be runnable on CS ugrad machines and be compatible with Go version 1.9.2.
  • Your code does not need to check or handle ErrMessage replies from the aserver or fserver. However, you may find it useful to check for these replies during debugging.
  • Your code may assume that UDP is reliable and not implement any retransmission.
  • You must use the message types given out in the initial code.
  • Your solution can only use standard library Go packages.
  • Your solution code must be Gofmt'd using gofmt.

Solution spec

Write a single go program called client.go that acts as a client in the protocol described above. Your program must implement the following command line usage:

go run client.go [local UDP ip:port] [local TCP ip:port] [aserver UDP ip:port]

  • [local UDP ip:port] : local UDP address that the client uses to connect to the aserver (i.e., the external IP of the machine the client is running on)
  • [local TCP ip:port] : local TCP address that the client uses to connect to the fserver
  • [aserver UDP ip:port] : the UDP address on which the aserver receives new client connections

Starter code and testing servers

Download the starter code. The aserver is running at IP:port 198.162.33.54:5555. The fserver is also running.

Rough grading scheme

  • 10% : Client properly initiates contact with the aserver
  • 40% : Client computes a valid secret and communicates it to the aserver
  • 25% : Client properly communicates to the fserver and provides the right fnonce
  • 25% : Client prints out the right fortune message

Extra credit

The rank returned by the fserver gives you an idea of how fast your solution is relative to other students in the course (who have tested their solutions). In our extra credit testing we will use the same nonce for all student solutions, and all solutions with a rank <= 10 will receive the extra credit of 2% added to their final course grade.



Make sure to follow the course collaboration policy and refer to the assignments instructions that detail how to submit your solution.