API Coordinator Refactor

This commit is contained in:
ToniRamirezM
2020-10-27 17:28:23 +01:00
parent e5d1143a7e
commit b521a77fc5
8 changed files with 175 additions and 166 deletions

View File

@@ -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 @@ func TestMain(m *testing.M) {
}
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 @@ func TestMain(m *testing.M) {
blocks: blocks,
tokens: tokensUSD,
batches: genTestBatches(blocks, batches),
coordinators: apiCoordinators,
coordinators: coordinators,
usrAddr: ethAddrToHez(usrAddr),
usrBjj: bjjToString(usrBjj),
accs: accs,
@@ -1162,58 +1161,6 @@ func assertPoolTx(t *testing.T, expected, actual sendPoolTx) {
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"

57
api/coordinator.go Normal file
View File

@@ -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,
})
}

93
api/coordinator_test.go Normal file
View File

@@ -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)
}

View File

@@ -578,48 +578,6 @@ func poolL2TxReadToSend(dbTx *l2db.PoolL2TxRead) *sendPoolTx {
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 {

View File

@@ -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{

View File

@@ -145,7 +145,7 @@ func assertTokensAPIs(t *testing.T, expected, actual []historydb.TokenWithUSD) {
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])