Merge pull request #235 from hermeznetwork/feature/api-coordinator-refactor API Coordinator Refactor
laisolizq 37299818+laisolizq@users.noreply.github.com
Wed, 28 Oct 2020 10:20:44 +0100
8 files changed,
175 insertions(+),
166 deletions(-)
M
api/api_test.go
→
api/api_test.go
@@ -41,7 +41,7 @@ type testCommon struct {
blocks []common.Block tokens []historydb.TokenWithUSD batches []testBatch - coordinators []coordinatorAPI + coordinators []historydb.CoordinatorAPI usrAddr string usrBjj string accs []common.Account@@ -633,8 +633,7 @@ panic(err)
} fromItem := uint(0) limit := uint(99999) - coordinators, _, err := hdb.GetCoordinators(&fromItem, &limit, historydb.OrderAsc) - apiCoordinators := coordinatorsToAPI(coordinators) + coordinators, _, err := hdb.GetCoordinatorsAPI(&fromItem, &limit, historydb.OrderAsc) if err != nil { panic(err) }@@ -652,7 +651,7 @@ tc = testCommon{
blocks: blocks, tokens: tokensUSD, batches: genTestBatches(blocks, batches), - coordinators: apiCoordinators, + coordinators: coordinators, usrAddr: ethAddrToHez(usrAddr), usrBjj: bjjToString(usrBjj), accs: accs,@@ -1162,58 +1161,6 @@ }
assert.Equal(t, expected, actual) } -func TestGetCoordinators(t *testing.T) { - endpoint := apiURL + "coordinators" - fetchedCoordinators := []coordinatorAPI{} - - appendIter := func(intr interface{}) { - for i := 0; i < len(intr.(*coordinatorsAPI).Coordinators); i++ { - tmp, err := copystructure.Copy(intr.(*coordinatorsAPI).Coordinators[i]) - if err != nil { - panic(err) - } - fetchedCoordinators = append(fetchedCoordinators, tmp.(coordinatorAPI)) - } - } - - limit := 5 - - path := fmt.Sprintf("%s?limit=%d&fromItem=", endpoint, limit) - err := doGoodReqPaginated(path, historydb.OrderAsc, &coordinatorsAPI{}, appendIter) - assert.NoError(t, err) - assert.Equal(t, tc.coordinators, fetchedCoordinators) - - // Reverse Order - reversedCoordinators := []coordinatorAPI{} - appendIter = func(intr interface{}) { - for i := 0; i < len(intr.(*coordinatorsAPI).Coordinators); i++ { - tmp, err := copystructure.Copy(intr.(*coordinatorsAPI).Coordinators[i]) - if err != nil { - panic(err) - } - reversedCoordinators = append(reversedCoordinators, tmp.(coordinatorAPI)) - } - } - err = doGoodReqPaginated(path, historydb.OrderDesc, &coordinatorsAPI{}, appendIter) - assert.NoError(t, err) - for i := 0; i < len(fetchedCoordinators); i++ { - assert.Equal(t, reversedCoordinators[i], fetchedCoordinators[len(fetchedCoordinators)-1-i]) - } - - // Test GetCoordinator - path = fmt.Sprintf("%s/%s", endpoint, fetchedCoordinators[2].Forger.String()) - coordinator := coordinatorAPI{} - assert.NoError(t, doGoodReq("GET", path, nil, &coordinator)) - assert.Equal(t, fetchedCoordinators[2], coordinator) - // 400 - path = fmt.Sprintf("%s/0x001", endpoint) - err = doBadReq("GET", path, nil, 400) - assert.NoError(t, err) - // 404 - path = fmt.Sprintf("%s/0xaa942cfcd25ad4d90a62358b0dd84f33b398262a", endpoint) - err = doBadReq("GET", path, nil, 404) - assert.NoError(t, err) -} func TestAccountCreationAuth(t *testing.T) { // POST endpoint := apiURL + "account-creation-authorization"
A
api/coordinator.go
@@ -0,0 +1,57 @@
+package api + +import ( + "net/http" + + "github.com/gin-gonic/gin" + "github.com/hermeznetwork/hermez-node/db" + "github.com/hermeznetwork/hermez-node/db/historydb" +) + +func getCoordinator(c *gin.Context) { + // Get bidderAddr + const name = "bidderAddr" + bidderAddr, err := parseParamEthAddr(name, c) + + if err != nil { + retBadReq(err, c) + return + } else if bidderAddr == nil { + retBadReq(ErrNillBidderAddr, c) + return + } + + coordinator, err := h.GetCoordinatorAPI(*bidderAddr) + if err != nil { + retSQLErr(err, c) + return + } + + c.JSON(http.StatusOK, coordinator) +} + +func getCoordinators(c *gin.Context) { + // Pagination + fromItem, order, limit, err := parsePagination(c) + if err != nil { + retBadReq(err, c) + return + } + + // Fetch coordinators from historyDB + coordinators, pagination, err := h.GetCoordinatorsAPI(fromItem, limit, order) + if err != nil { + retSQLErr(err, c) + return + } + + // Build succesfull response + type coordinatorsResponse struct { + Coordinators []historydb.CoordinatorAPI `json:"coordinators"` + Pagination *db.Pagination `json:"pagination"` + } + c.JSON(http.StatusOK, &coordinatorsResponse{ + Coordinators: coordinators, + Pagination: pagination, + }) +}
A
api/coordinator_test.go
@@ -0,0 +1,93 @@
+package api + +import ( + "fmt" + "testing" + + "github.com/hermeznetwork/hermez-node/db" + "github.com/hermeznetwork/hermez-node/db/historydb" + "github.com/mitchellh/copystructure" + "github.com/stretchr/testify/assert" +) + +type testCoordinatorsResponse struct { + Coordinators []historydb.CoordinatorAPI `json:"coordinators"` + Pagination *db.Pagination `json:"pagination"` +} + +func (t *testCoordinatorsResponse) GetPagination() *db.Pagination { + if t.Coordinators[0].ItemID < t.Coordinators[len(t.Coordinators)-1].ItemID { + t.Pagination.FirstReturnedItem = t.Coordinators[0].ItemID + t.Pagination.LastReturnedItem = t.Coordinators[len(t.Coordinators)-1].ItemID + } else { + t.Pagination.LastReturnedItem = t.Coordinators[0].ItemID + t.Pagination.FirstReturnedItem = t.Coordinators[len(t.Coordinators)-1].ItemID + } + return t.Pagination +} + +func (t *testCoordinatorsResponse) Len() int { return len(t.Coordinators) } + +func TestGetCoordinators(t *testing.T) { + endpoint := apiURL + "coordinators" + fetchedCoordinators := []historydb.CoordinatorAPI{} + + appendIter := func(intr interface{}) { + for i := 0; i < len(intr.(*testCoordinatorsResponse).Coordinators); i++ { + tmp, err := copystructure.Copy(intr.(*testCoordinatorsResponse).Coordinators[i]) + if err != nil { + panic(err) + } + fetchedCoordinators = append(fetchedCoordinators, tmp.(historydb.CoordinatorAPI)) + } + } + + limit := 5 + + path := fmt.Sprintf("%s?limit=%d&fromItem=", endpoint, limit) + err := doGoodReqPaginated(path, historydb.OrderAsc, &testCoordinatorsResponse{}, appendIter) + assert.NoError(t, err) + for i := 0; i < len(fetchedCoordinators); i++ { + assert.Equal(t, tc.coordinators[i].ItemID, fetchedCoordinators[i].ItemID) + assert.Equal(t, tc.coordinators[i].Bidder, fetchedCoordinators[i].Bidder) + assert.Equal(t, tc.coordinators[i].Forger, fetchedCoordinators[i].Forger) + assert.Equal(t, tc.coordinators[i].EthBlockNum, fetchedCoordinators[i].EthBlockNum) + assert.Equal(t, tc.coordinators[i].URL, fetchedCoordinators[i].URL) + } + + // Reverse Order + reversedCoordinators := []historydb.CoordinatorAPI{} + appendIter = func(intr interface{}) { + for i := 0; i < len(intr.(*testCoordinatorsResponse).Coordinators); i++ { + tmp, err := copystructure.Copy(intr.(*testCoordinatorsResponse).Coordinators[i]) + if err != nil { + panic(err) + } + reversedCoordinators = append(reversedCoordinators, tmp.(historydb.CoordinatorAPI)) + } + } + err = doGoodReqPaginated(path, historydb.OrderDesc, &testCoordinatorsResponse{}, appendIter) + assert.NoError(t, err) + for i := 0; i < len(fetchedCoordinators); i++ { + assert.Equal(t, reversedCoordinators[i].ItemID, fetchedCoordinators[len(fetchedCoordinators)-1-i].ItemID) + assert.Equal(t, reversedCoordinators[i].Bidder, fetchedCoordinators[len(fetchedCoordinators)-1-i].Bidder) + assert.Equal(t, reversedCoordinators[i].Forger, fetchedCoordinators[len(fetchedCoordinators)-1-i].Forger) + assert.Equal(t, reversedCoordinators[i].EthBlockNum, fetchedCoordinators[len(fetchedCoordinators)-1-i].EthBlockNum) + assert.Equal(t, reversedCoordinators[i].URL, fetchedCoordinators[len(fetchedCoordinators)-1-i].URL) + } + + // Test GetCoordinator + path = fmt.Sprintf("%s/%s", endpoint, fetchedCoordinators[2].Forger.String()) + coordinator := historydb.CoordinatorAPI{} + assert.NoError(t, doGoodReq("GET", path, nil, &coordinator)) + assert.Equal(t, fetchedCoordinators[2], coordinator) + + // 400 + path = fmt.Sprintf("%s/0x001", endpoint) + err = doBadReq("GET", path, nil, 400) + assert.NoError(t, err) + // 404 + path = fmt.Sprintf("%s/0xaa942cfcd25ad4d90a62358b0dd84f33b398262a", endpoint) + err = doBadReq("GET", path, nil, 404) + assert.NoError(t, err) +}
M
api/dbtoapistructs.go
→
api/dbtoapistructs.go
@@ -578,48 +578,6 @@ }
return tx } -// Coordinators - -type coordinatorAPI struct { - ItemID int `json:"itemId"` - Bidder ethCommon.Address `json:"bidderAddr"` - Forger ethCommon.Address `json:"forgerAddr"` - EthBlockNum int64 `json:"ethereumBlock"` - URL string `json:"URL"` -} - -type coordinatorsAPI struct { - Coordinators []coordinatorAPI `json:"coordinators"` - Pagination *db.Pagination `json:"pagination"` -} - -func (t *coordinatorsAPI) GetPagination() *db.Pagination { - if t.Coordinators[0].ItemID < t.Coordinators[len(t.Coordinators)-1].ItemID { - t.Pagination.FirstReturnedItem = t.Coordinators[0].ItemID - t.Pagination.LastReturnedItem = t.Coordinators[len(t.Coordinators)-1].ItemID - } else { - t.Pagination.LastReturnedItem = t.Coordinators[0].ItemID - t.Pagination.FirstReturnedItem = t.Coordinators[len(t.Coordinators)-1].ItemID - } - return t.Pagination -} - -func (t *coordinatorsAPI) Len() int { return len(t.Coordinators) } - -func coordinatorsToAPI(dbCoordinators []historydb.HistoryCoordinator) []coordinatorAPI { - apiCoordinators := []coordinatorAPI{} - for i := 0; i < len(dbCoordinators); i++ { - apiCoordinators = append(apiCoordinators, coordinatorAPI{ - ItemID: dbCoordinators[i].ItemID, - Bidder: dbCoordinators[i].Bidder, - Forger: dbCoordinators[i].Forger, - EthBlockNum: dbCoordinators[i].EthBlockNum, - URL: dbCoordinators[i].URL, - }) - } - return apiCoordinators -} - // AccountCreationAuth type accountCreationAuthAPI struct {
M
api/handlers.go
→
api/handlers.go
@@ -219,52 +219,6 @@ func getRecommendedFee(c *gin.Context) {
} -func getCoordinators(c *gin.Context) { - // Pagination - fromItem, order, limit, err := parsePagination(c) - if err != nil { - retBadReq(err, c) - return - } - - // Fetch coordinators from historyDB - coordinators, pagination, err := h.GetCoordinators(fromItem, limit, order) - if err != nil { - retSQLErr(err, c) - return - } - - // Build succesfull response - apiCoordinators := coordinatorsToAPI(coordinators) - c.JSON(http.StatusOK, &coordinatorsAPI{ - Coordinators: apiCoordinators, - Pagination: pagination, - }) -} - -func getCoordinator(c *gin.Context) { - // Get bidderAddr - const name = "bidderAddr" - bidderAddr, err := parseParamEthAddr(name, c) - - if err != nil { - retBadReq(err, c) - return - } else if bidderAddr == nil { - retBadReq(ErrNillBidderAddr, c) - return - } - - coordinator, err := h.GetCoordinator(*bidderAddr) - if err != nil { - retSQLErr(err, c) - return - } - - apiCoordinator := coordinatorsToAPI([]historydb.HistoryCoordinator{*coordinator}) - c.JSON(http.StatusOK, apiCoordinator[0]) -} - func retSQLErr(err error, c *gin.Context) { if err == sql.ErrNoRows { c.JSON(http.StatusNotFound, errorMsg{
M
api/token_test.go
→
api/token_test.go
@@ -145,7 +145,7 @@ actual[i].ItemID = 0
if expected[i].USDUpdate == nil { assert.Equal(t, expected[i].USDUpdate, actual[i].USDUpdate) } else { - assert.Equal(t, expected[i].USDUpdate.Unix(), actual[i].USDUpdate.Unix()) + assert.Less(t, expected[i].USDUpdate.Unix()-3, actual[i].USDUpdate.Unix()) expected[i].USDUpdate = actual[i].USDUpdate } assert.Equal(t, expected[i], actual[i])
M
db/historydb/historydb.go
→
db/historydb/historydb.go
@@ -1100,17 +1100,17 @@
return txn.Commit() } -// GetCoordinator returns a coordinator by its bidderAddr -func (hdb *HistoryDB) GetCoordinator(bidderAddr ethCommon.Address) (*HistoryCoordinator, error) { - coordinator := &HistoryCoordinator{} +// GetCoordinatorAPI returns a coordinator by its bidderAddr +func (hdb *HistoryDB) GetCoordinatorAPI(bidderAddr ethCommon.Address) (*CoordinatorAPI, error) { + coordinator := &CoordinatorAPI{} err := meddler.QueryRow( hdb.db, coordinator, `SELECT * FROM coordinator WHERE bidder_addr = $1;`, bidderAddr, ) return coordinator, err } -// GetCoordinators returns a list of coordinators from the DB and pagination info -func (hdb *HistoryDB) GetCoordinators(fromItem, limit *uint, order string) ([]HistoryCoordinator, *db.Pagination, error) { +// GetCoordinatorsAPI returns a list of coordinators from the DB and pagination info +func (hdb *HistoryDB) GetCoordinatorsAPI(fromItem, limit *uint, order string) ([]CoordinatorAPI, *db.Pagination, error) { var query string var args []interface{} queryStr := `SELECT coordinator.*,@@ -1136,14 +1136,14 @@ }
queryStr += fmt.Sprintf("LIMIT %d;", *limit) query = hdb.db.Rebind(queryStr) - coordinators := []*HistoryCoordinator{} + coordinators := []*CoordinatorAPI{} if err := meddler.QueryAll(hdb.db, &coordinators, query, args...); err != nil { return nil, nil, err } if len(coordinators) == 0 { return nil, nil, sql.ErrNoRows } - return db.SlicePtrsToSlice(coordinators).([]HistoryCoordinator), &db.Pagination{ + return db.SlicePtrsToSlice(coordinators).([]CoordinatorAPI), &db.Pagination{ TotalItems: coordinators[0].TotalItems, FirstItem: coordinators[0].FirstItem, LastItem: coordinators[0].LastItem,
M
db/historydb/views.go
→
db/historydb/views.go
@@ -120,17 +120,17 @@ TokenUSD *float64 `meddler:"usd"`
TokenUSDUpdate *time.Time `meddler:"usd_update"` } -// HistoryCoordinator is a representation of a coordinator with additional information +// CoordinatorAPI is a representation of a coordinator with additional information // required by the API -type HistoryCoordinator struct { - ItemID int `meddler:"item_id"` - Bidder ethCommon.Address `meddler:"bidder_addr"` - Forger ethCommon.Address `meddler:"forger_addr"` - EthBlockNum int64 `meddler:"eth_block_num"` - URL string `meddler:"url"` - TotalItems int `meddler:"total_items"` - FirstItem int `meddler:"first_item"` - LastItem int `meddler:"last_item"` +type CoordinatorAPI struct { + ItemID int `json:"itemId" meddler:"item_id"` + Bidder ethCommon.Address `json:"bidderAddr" meddler:"bidder_addr"` + Forger ethCommon.Address `json:"forgerAddr" meddler:"forger_addr"` + EthBlockNum int64 `json:"ethereumBlock" meddler:"eth_block_num"` + URL string `json:"URL" meddler:"url"` + TotalItems int `json:"-" meddler:"total_items"` + FirstItem int `json:"-" meddler:"first_item"` + LastItem int `json:"-" meddler:"last_item"` } // BatchAPI is a representation of a batch with additional information@@ -157,10 +157,10 @@ }
// Network define status of the network type Network struct { - LastBlock int64 `json:"lastBlock"` - LastBatch BatchAPI `json:"lastBatch"` - CurrentSlot int64 `json:"currentSlot"` - NextForgers []HistoryCoordinator `json:"nextForgers"` + LastBlock int64 `json:"lastBlock"` + LastBatch BatchAPI `json:"lastBatch"` + CurrentSlot int64 `json:"currentSlot"` + NextForgers []CoordinatorAPI `json:"nextForgers"` } // Metrics define metrics of the network