powgwey

module
v0.0.0-...-23d494c Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 24, 2022 License: MIT

README

ProofOfWork gateway to simple tcp service.

1. Problem statement

Test task for Server Engineer

Design and implement “Word of Wisdom” tcp server.
• TCP server should be protected from DDOS attacks with the Prof of Work (https://en.wikipedia.org/wiki/Proof_of_work), the challenge-response protocol should be used.
• The choice of the POW algorithm should be explained.
• After Prof Of Work verification, server should send one of the quotes from “word of wisdom” book or any other collection of the quotes.
• Docker file should be provided both for the server and for the client that solves the POW challenge

2. How to run

2.1. Requirements

There are some issues, which I will fix shortly. https://github.com/svkior/powgwey/issues

Possibly can work everywhere on Linux/MacOS X, but tested on this config:

  1. OS: Mac OS X 12.5.1
  2. Docker Desktop 4.4.2+
  3. GNU Make 3.81
  4. curl 7.79.1
  5. code is compatible with golang 1.18.3

There is no needence for installing golang locally, need access to the Internet for a first fime

May be some issues when running on m1 mac's

2.2. List of all available commands

To list all of the available commands just type:

make help
2.3. Building base image

The base image is used by other images to build, lint, test and check software in containers.

make build-base

Builind server image:

make build-server

Building client image:

make build-client
2.4. Linter check
make lint
2.5. Passing tests
make test
2.6. Monitoring environment

TODO: Still not works https://github.com/svkior/powgwey/issues/31

make start-monitoring
2.7. Start server
make start-server
2.8. Start client
make start-client
2.9. Start load-test

If server is started we can run load test.

make start-loadtest
2.10. Update quotes from another repo
make update-quotes

3. Solution

3.1. Sequence diagram

WiP: https://github.com/svkior/powgwey/issues/20

sequenceDiagram
    autonumber
    participant C as Client
    participant TCP as TCP Service
    participant PoW as PoW Service
    participant Q as Quotes Service
    participant S as Storage
    participant M as Monitoring

    C->>TCP: TCP Connect
    TCP->>TCP: Accept
    TCP->>M: Increment Income
    C->>TCP: PoW request
   TCP->>PoW: PoW request
    PoW->>M: Get 1m AVG Load
    activate M
    M-->>PoW: Current Load
    deactivate M 
    activate PoW
    PoW->>PoW: Generate Puzzle
    PoW-->>TCP: Puzzle
    deactivate PoW   
    TCP-->>C: Puzzle
    activate C
    C->>C: Solve
    C->>TCP: Solution
    deactivate C
    TCP->>PoW: Solution
    PoW->>PoW: Verify
    alt Solution is correct
        PoW-->>TCP: OK
        activate TCP
        TCP->>Q: GetRandomQuote
        Q->>S: GetRandomQuote
        S-->>Q: Quote
        Q-->>TCP: Quote
        TCP-->>C: Quote
        deactivate TCP
        TCP->>M: Increment Success
        TCP->>M: time of processing success
    else Solution is incorrect
        PoW-->>TCP: Not OK
        TCP->>M: Increment Failed 
        TCP->>M: time of processing Failed
    end
    TCP-->>C: Close connection
3.2. Common way of configuration of all service components

I choosed viper.

3.3. Quotes

I've taked quotes from different repo on github.

Permlink is : https://raw.githubusercontent.com/msramalho/json-tv-quotes/master/quotes.json

Service component "quotes" is located in server_internal/services folder

  • configuration of this component is located in server_internal/config/quotes
3.4. Quotes Model

Component model: I've taked quotes from different repo on github.

Permlink is : https://raw.githubusercontent.com/msramalho/json-tv-quotes/master/quotes.json

Service component "quotes" is located in server_internal/services folder

  • configuration of this component is located in server_internal/config/quotes

Component model:

  • NewQuotesService
  • quotesService:
    • Init() Initialize component
    • Shutdown() Shutdown component
    • GetQuote() Get Quote

It can be assumed that in a highly loaded project, the payload will take some time. Let's limit the fictitious load of the variable QUOTES_PROCESSING_TIME We will create a work queue from QUOTES_WORKERS

3.5. TCP Server Component

According to https://github.com/svkior/powgwey/issues/12 I decided to implement No8.

Because for gaming industry the most important feature is a lattency. Second important is maximum throughput.

If we can provide lattency, we can spend more mony for servers.

3.6. PoW Algritm

Descisions: https://github.com/svkior/powgwey/issues/15

I've found article https://users.soe.ucsc.edu/~abadi/Papers/memory-longer-acm.pdf and

Memory-bound PoW is better because memory access performance is less sensitive to hardware and should generally work on both low and high-end hardware. In addition, it is expected that the performance of such an algorithm will be less sensitive to an increase in processor speed.

General design matches a proposed one where Server generates a random x0 and applies F() to it k times resulting in xk.

Client knows all information about the parameters of algorithm except the x0 and is expected to try all different paths towards x0.

When x0 is found, Client compares a checksum of a sequence to the checksum of a valid sequence received from the Server. When checksum matches, solution is found. Is checksums don't match, client goes for another sequence until valid is found.

3.7. Function F()

Implementation of F() will greatly affect difficulty and efficiency of an algorithm. It is desirable that there are x and x', where F(x)=F(x'). This requires client to traverse both paths to check sequences, increasing required work.

In addition, it's required that calling inverted F() is slower that accessing inversion table, encouraging client to use memory instead of CPU.

There is possibillity to change current implementation of F() if needed.

3.8. Challenge difficulty

Difficulty of this PoW can be configured with two parameters k and n.

k represents a number of times F() is applied. Increasing this parameter will result in longer sequences and will affect both Client and Server

n represents a range of possible values, which will be in a range [0, 2^n). Increasing it will mostly affect Client and not a Server, since Client will have to generate a larger inversion table and process more sequences, while Server will just generate a larger numbers.

TODO: https://github.com/svkior/powgwey/issues/36

4. Server environment variables

###############################################
#  -=(* TCP SERVER CONFIG  *)=-
###############################################

SRV_PORT=8000
SRV_HOST=0.0.0.0
SRV_NET_READ_TIMEOUT=1s
SRV_NET_WRITE_TIMEOUT=1s

###############################################
#  -=(* QUOTES STORAGE COMPONENT CONFIG  *)=-
###############################################

# Fiction processing time of getting quotes
SRV_QUOTES_PROCESSING_TIME=0.3s

# Filepath of quotes database
SRV_QUOTES_FILEPATH=/opt/user/data/movies.json

###############################################
#  -=(* QUOTES SERVICE COMPONENT CONFIG  *)=-
###############################################

# Number of workers in Quotes workers queue
SRV_QUOTES_WORKERS=100

5. Client command lines

We have single parameter for describing connection string.

 client -server=127.0.0.1:8000

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL