The details of the assignment here
For the sake of simplicity, here are assumptions based on the requirements of the assignment:
- The project runs in a single thread, parsing blocks one by one. No re-org handling.
GetTransactions
return transactions of the latest parsed block, no pagination.- Only store the latest block's transaction data for each address. No historical data is saved.
- If the latest parsed block does not have transactions for the subscribed address -> return empty list.
- On Ethereum Blockchain the block time is 12s (approximately), meaning when crawl latest block on the chain, we can let the job run interval every 4s.
- Avoid usage of external libraries: gin-gonic/gin, go-ethereum, etc.
- Use Go's
net/http
package to make requests to the Ethereum JSONRPC API. - Use Go's built-in data structures to store in memory data.
- Use simple REST API for expose public interface.
- Let
testify
is the exception because it is used to support write tests and mock.
- Use Go's
Interval (every 4 seconds) running job to get latest block from ethereum and extract transactions filtered by subscribed addresses.
Using the Repository to get addresses and save block data.
Call RPC node to get block data:
Handle and expose public interface for biz logic:
type Parser interface {
// last parsed block
GetCurrentBlock() int
// add address to observer
Subscribe(address string) bool
// list of inbound or outbound transactions for an address
GetTransactions(address string) []Transaction
}
Handle storage queries:
type Repository interface {
// last parsed block
GetCurrentBlock() (int, error)
// get list of subscribed addresses
GetAddresses() ([]string, error)
// list of transactions for an address
GetTransactions(address string) ([]Transaction, error)
// add a address to list of subscription
AddAddress(address string) error
// save the list of transactions
SaveTransactions(blockNum int, txn []Transaction) error
}
When run main, the code will start both the crawler job and the APIs server
go run cmd/tx-parser/main.go
Example of the 3 APIs:
- GET /current-block
curl --location 'http://localhost:8080/current-block'
- POST /subscribe
curl --location 'http://localhost:8080/subscribe' \
--header 'Content-Type: application/json' \
--data '{
"address": "0xf15689636571dba322b48e9ec9ba6cfb3df818e1"
}'
- GET /transactions
curl --location 'http://localhost:8080/transactions?address=0x95222290dd7278aa3ddd389cc1e1d165cc4bafe5'