diff --git a/api/account_test.go b/api/account_test.go index de25355..7cf93ad 100644 --- a/api/account_test.go +++ b/api/account_test.go @@ -81,7 +81,7 @@ func TestGetAccounts(t *testing.T) { assert.LessOrEqual(t, len(fetchedAccounts), len(tc.accounts)) fetchedAccounts = []testAccount{} // Filter by ethAddr - path = fmt.Sprintf("%s?hermezEthereumAddress=%s&limit=%d&fromItem=", endpoint, tc.accounts[0].EthAddr, limit) + path = fmt.Sprintf("%s?hermezEthereumAddress=%s&limit=%d&fromItem=", endpoint, tc.accounts[3].EthAddr, limit) err = doGoodReqPaginated(path, historydb.OrderAsc, &testAccountsResponse{}, appendIter) assert.NoError(t, err) assert.Greater(t, len(fetchedAccounts), 0) diff --git a/api/api.go b/api/api.go index 9c1c0fd..0f45528 100644 --- a/api/api.go +++ b/api/api.go @@ -2,6 +2,7 @@ package api import ( "errors" + "sync" "github.com/gin-gonic/gin" "github.com/hermeznetwork/hermez-node/common" @@ -18,6 +19,7 @@ const ( // Status define status of the network type Status struct { + sync.RWMutex Network Network `json:"network"` Metrics historydb.Metrics `json:"metrics"` Rollup common.RollupVariables `json:"rollup"` @@ -60,8 +62,9 @@ func NewAPI( AuctionConstants: config.AuctionConstants, WDelayerConstants: config.WDelayerConstants, }, - s: sdb, - l2: l2db, + s: sdb, + l2: l2db, + status: Status{}, } // Add coordinator endpoints diff --git a/api/api_test.go b/api/api_test.go index eb1652f..e2e69e2 100644 --- a/api/api_test.go +++ b/api/api_test.go @@ -58,8 +58,8 @@ var SetBlockchain = ` // close Block:0, Batch:0 > batch - CreateAccountDeposit(0) A: 111111111 - CreateAccountDeposit(1) C: 222222222 + CreateAccountDeposit(0) A: 11111111100000000000 + CreateAccountDeposit(1) C: 22222222200000000000 CreateAccountCoordinator(0) C // close Block:0, Batch:1 @@ -68,7 +68,7 @@ var SetBlockchain = ` // Coord(0): 0, Coord(1): 0 // C(0): 0 - CreateAccountDeposit(1) A: 333333333 + CreateAccountDeposit(1) A: 33333333300000000000 // close Block:0, Batch:2 > batchL1 @@ -76,40 +76,40 @@ var SetBlockchain = ` // close Block:0, Batch:3 > batchL1 - CreateAccountDepositTransfer(0) B-A: 444444444, 1234444444 // to_eth_addr is NULL + CreateAccountDepositTransfer(0) B-A: 44444444400000000000, 123444444400000000000 // close Block:0, Batch:4 > batchL1 - CreateAccountDeposit(0) D: 555555555 + CreateAccountDeposit(0) D: 55555555500000000000 // close Block:0, Batch:5 > batchL1 CreateAccountCoordinator(1) B - Transfer(1) A-B: 111111 (2) // to_eth_addr is NULL - Transfer(0) B-C: 222222 (3) + Transfer(1) A-B: 11111100000000000 (2) + Transfer(0) B-C: 22222200000000000 (3) // close Block:0, Batch:6 > batchL1 // forge L1User{1}, forge L1Coord{2}, forge L2{2} - Deposit(0) C: 666666666 - DepositTransfer(0) C-D: 777777777, 123777777 // to_eth_addr is NULL + Deposit(0) C: 66666666600000000000 + DepositTransfer(0) C-D: 77777777700000000000, 12377777700000000000 - Transfer(0) A-B: 333333 (111) - Transfer(0) C-A: 444444 (222) - Transfer(1) B-C: 555555 (123) - Exit(0) A: 666666 (44) + Transfer(0) A-B: 33333300000000000 (111) + Transfer(0) C-A: 44444400000000000 (222) + Transfer(1) B-C: 55555500000000000 (123) + Exit(0) A: 66666600000000000 (44) - ForceTransfer(0) D-B: 777777 // to_eth_addr is NULL - ForceExit(0) B: 888888 + ForceTransfer(0) D-B: 77777700000000000 + ForceExit(0) B: 88888800000000000 // close Block:0, Batch:7 > batchL1 > block - Transfer(0) D-A: 999999 (77) - Transfer(0) B-D: 123123 (55) + Transfer(0) D-A: 99999900000000000 (77) + Transfer(0) B-D: 12312300000000000 (55) // close Block:1, Batch:0 > batchL1 diff --git a/api/aux_test.go b/api/aux_test.go index 6505bd3..eea6f40 100644 --- a/api/aux_test.go +++ b/api/aux_test.go @@ -15,9 +15,9 @@ func AddAditionalInformation(blocks []common.BlockData) { blocks[i].Block.Timestamp = time.Now().Add(time.Second * 13).UTC() blocks[i].Block.Hash = ethCommon.BigToHash(big.NewInt(blocks[i].Block.Num)) for j := range blocks[i].Rollup.AddedTokens { - blocks[i].Rollup.AddedTokens[j].Name = "NAME" + strconv.Itoa(int(blocks[i].Rollup.AddedTokens[j].TokenID)) - blocks[i].Rollup.AddedTokens[j].Symbol = strconv.Itoa(int(blocks[i].Rollup.AddedTokens[j].TokenID)) - blocks[i].Rollup.AddedTokens[j].Decimals = uint64(blocks[i].Rollup.AddedTokens[j].TokenID + 1) + blocks[i].Rollup.AddedTokens[j].Name = "Test Token " + strconv.Itoa(int(blocks[i].Rollup.AddedTokens[j].TokenID)) + blocks[i].Rollup.AddedTokens[j].Symbol = "TKN" + strconv.Itoa(int(blocks[i].Rollup.AddedTokens[j].TokenID)) + blocks[i].Rollup.AddedTokens[j].Decimals = 18 } for x := range blocks[i].Rollup.Batches { for q := range blocks[i].Rollup.Batches[x].CreatedAccounts { diff --git a/api/state.go b/api/state.go index e4fd075..af941ea 100644 --- a/api/state.go +++ b/api/state.go @@ -43,24 +43,33 @@ var bootCoordinator historydb.CoordinatorAPI = historydb.CoordinatorAPI{ func (a *API) getState(c *gin.Context) { // TODO: There are no events for the buckets information, so now this information will be 0 - c.JSON(http.StatusOK, a.status) + a.status.RLock() + status := a.status //nolint + a.status.RUnlock() + c.JSON(http.StatusOK, status) //nolint } // SC Vars // SetRollupVariables set Status.Rollup variables func (a *API) SetRollupVariables(rollupVariables common.RollupVariables) { + a.status.Lock() a.status.Rollup = rollupVariables + a.status.Unlock() } // SetWDelayerVariables set Status.WithdrawalDelayer variables func (a *API) SetWDelayerVariables(wDelayerVariables common.WDelayerVariables) { + a.status.Lock() a.status.WithdrawalDelayer = wDelayerVariables + a.status.Unlock() } // SetAuctionVariables set Status.Auction variables func (a *API) SetAuctionVariables(auctionVariables common.AuctionVariables) { + a.status.Lock() a.status.Auction = auctionVariables + a.status.Unlock() } // Network @@ -78,25 +87,27 @@ func (a *API) UpdateNetworkInfo( lastEthBlock, lastSyncBlock common.Block, lastBatchNum common.BatchNum, currentSlot int64, ) error { - a.status.Network.LastSyncBlock = lastSyncBlock.Num - a.status.Network.LastEthBlock = lastEthBlock.Num lastBatch, err := a.h.GetBatchAPI(lastBatchNum) if err != nil { return err } - a.status.Network.LastBatch = *lastBatch - a.status.Network.CurrentSlot = currentSlot lastClosedSlot := currentSlot + int64(a.status.Auction.ClosedAuctionSlots) - nextForgers, err := a.GetNextForgers(lastSyncBlock, currentSlot, lastClosedSlot) + nextForgers, err := a.getNextForgers(lastSyncBlock, currentSlot, lastClosedSlot) if err != nil { return err } + a.status.Lock() + a.status.Network.LastSyncBlock = lastSyncBlock.Num + a.status.Network.LastEthBlock = lastEthBlock.Num + a.status.Network.LastBatch = *lastBatch + a.status.Network.CurrentSlot = currentSlot a.status.Network.NextForgers = nextForgers + a.status.Unlock() return nil } -// GetNextForgers returns next forgers -func (a *API) GetNextForgers(lastBlock common.Block, currentSlot, lastClosedSlot int64) ([]NextForger, error) { +// getNextForgers returns next forgers +func (a *API) getNextForgers(lastBlock common.Block, currentSlot, lastClosedSlot int64) ([]NextForger, error) { secondsPerBlock := int64(15) //nolint:gomnd // currentSlot and lastClosedSlot included limit := uint(lastClosedSlot - currentSlot + 1) @@ -144,11 +155,16 @@ func (a *API) GetNextForgers(lastBlock common.Block, currentSlot, lastClosedSlot // UpdateMetrics update Status.Metrics information func (a *API) UpdateMetrics() error { - metrics, err := a.h.GetMetrics(a.status.Network.LastBatch.BatchNum) + a.status.RLock() + batchNum := a.status.Network.LastBatch.BatchNum + a.status.RUnlock() + metrics, err := a.h.GetMetrics(batchNum) if err != nil { return err } + a.status.Lock() a.status.Metrics = *metrics + a.status.Unlock() return nil } @@ -160,8 +176,10 @@ func (a *API) UpdateRecommendedFee() error { if err != nil { return err } + a.status.Lock() a.status.RecommendedFee.ExistingAccount = feeExistingAccount a.status.RecommendedFee.CreatesAccount = createAccountExtraFeePercentage * feeExistingAccount a.status.RecommendedFee.CreatesAccountAndRegister = createAccountInternalExtraFeePercentage * feeExistingAccount + a.status.Unlock() return nil } diff --git a/api/state_test.go b/api/state_test.go index 1eabdde..88370aa 100644 --- a/api/state_test.go +++ b/api/state_test.go @@ -58,7 +58,7 @@ func TestNextForgers(t *testing.T) { lastBlock := tc.blocks[len(tc.blocks)-1] for i := int64(0); i < tc.slots[len(tc.slots)-1].SlotNum; i++ { lastClosedSlot := i + int64(api.status.Auction.ClosedAuctionSlots) - nextForgers, err := api.GetNextForgers(tc.blocks[len(tc.blocks)-1], i, lastClosedSlot) + nextForgers, err := api.getNextForgers(tc.blocks[len(tc.blocks)-1], i, lastClosedSlot) assert.NoError(t, err) for j := i; j <= lastClosedSlot; j++ { for q := range nextForgers { diff --git a/api/swagger.yml b/api/swagger.yml index b9bbbd1..d9f5e22 100644 --- a/api/swagger.yml +++ b/api/swagger.yml @@ -1852,69 +1852,161 @@ components: $ref: '#/components/schemas/PendingItems' example: transactions: + - L1Info: + ethereumBlockNum: 3 + historicLoadAmountUSD: + loadAmount: '0' + toForgeL1TransactionsNum: 7 + userOrigin: true + L1orL2: L1 + L2Info: + amount: '88888800000000000' + batchNum: 9 + fromAccountIndex: hez:ETH:262 + fromBJJ: hez:Mj_xDCjfN-y3h_4hbhEdtkqnz6LFF1Cf4AV_8IoQswwh + fromHezEthereumAddress: hez:0x2B5AD5c4795c026514f8317c7a215E218DcCD6cF + historicUSD: 44.4444 + id: '0x000000000000000007000300' + itemId: 28 + position: 3 + timestamp: '2020-11-26T09:18:40.004749Z' + toAccountIndex: hez:EXIT:1 + toBJJ: + toHezEthereumAddress: + token: + USD: 500 + decimals: 18 + ethereumAddress: '0x0000000000000000000000000000000000000000' + ethereumBlockNum: 0 + fiatUpdate: '2020-11-26T09:18:27.034866Z' + id: 0 + itemId: 1 + name: Ether + symbol: ETH + type: ForceExit - L1Info: L1orL2: L2 L2Info: - fee: 44 - historicFeeUSD: 0.01 - nonce: 301 - amount: '301' - batchNum: 1 - fromAccountIndex: hez:SCC:276 - fromBJJ: hez:p_OohTzjzZnD3Sw93HQlK13DSxfD6lyvbfhh2kBsV6Z4 - fromHezEthereumAddress: hez:0x0000000000000000000000000000000000000114 - historicUSD: 44.72 - id: '0x02000000000000000000002c' - itemId: 1 - position: 4 - timestamp: '2020-11-17T14:08:12.197554Z' - toAccountIndex: hez:6:276 - toBJJ: hez:p_OohTzjzZnD3Sw93HQlK13DSxfD6lyvbfhh2kBsV6Z4 - toHezEthereumAddress: hez:0x0000000000000000000000000000000000000114 + fee: 123 + historicFeeUSD: 2.15037380962404 + nonce: 1 + amount: '55555500000000000' + batchNum: 8 + fromAccountIndex: hez:TKN1:264 + fromBJJ: hez:Mj_xDCjfN-y3h_4hbhEdtkqnz6LFF1Cf4AV_8IoQswwh + fromHezEthereumAddress: hez:0x2B5AD5c4795c026514f8317c7a215E218DcCD6cF + historicUSD: 23.4999765 + id: '0x020000000001080000000001' + itemId: 19 + position: 2 + timestamp: '2020-11-26T09:18:40.004749Z' + toAccountIndex: hez:TKN1:260 + toBJJ: hez:81h61cx0FKR1RXcLbHW8cZMPY8SR6yKU3ei4pmcLjpaQ + toHezEthereumAddress: hez:0x6813Eb9362372EEF6200f3b1dbC3f819671cBA69 token: - USD: 3478.67 - decimals: 7 - ethereumAddress: '0x0000000000000000000000000000000000000006' + USD: 423 + decimals: 18 + ethereumAddress: '0x0000000000000000000000000000000000000064' ethereumBlockNum: 2 - fiatUpdate: - id: 6 - itemId: 7 - name: Some Cool Coin - symbol: 'SCC' - type: Deposit - - L1Info: - ethereumBlockNum: 1 - historicLoadAmountUSD: 269 - loadAmount: '261' - toForgeL1TransactionsNum: 10 - userOrigin: true - L1orL2: L1 - L2Info: - amount: '261' - batchNum: 1 - fromAccountIndex: hez:ETH:276 - fromBJJ: hez:p_OohTzjzZnD3Sw93HQlK13DSxfD6lyvbfhh2kBsV6Z4 - fromHezEthereumAddress: hez:0x0000000000000000000000000000000000000114 - historicUSD: - id: '0x00000000000000000a000400' - itemId: 2 - position: 4 - timestamp: '2020-11-17T14:08:12.197554Z' - toAccountIndex: hez:ETH:276 - toBJJ: hez:p_OohTzjzZnD3Sw93HQlK13DSxfD6lyvbfhh2kBsV6Z4 - toHezEthereumAddress: hez:0x0000000000000000000000000000000000000114 + fiatUpdate: '2020-11-26T09:18:27.04357Z' + id: 1 + itemId: 2 + name: Test Token 1 + symbol: TKN1 + type: Transfer + - L1Info: + L1orL2: L2 + L2Info: + fee: 44 + historicFeeUSD: 0.1973587359744 + nonce: 2 + amount: '66666600000000000' + batchNum: 8 + fromAccountIndex: hez:ETH:259 + fromBJJ: hez:W6x4TZOAZ9mAqdOb3Xm_hKDLspaXfEfMMN4tXOkinS-W + fromHezEthereumAddress: hez:0x7E5F4552091A69125d5DfCb7b8C2659029395Bdf + historicUSD: 33.3333 + id: '0x020000000001030000000002' + itemId: 20 + position: 3 + timestamp: '2020-11-26T09:18:40.004749Z' + toAccountIndex: hez:EXIT:1 + toBJJ: + toHezEthereumAddress: token: - USD: 734.21 + USD: 500 decimals: 18 ethereumAddress: '0x0000000000000000000000000000000000000000' ethereumBlockNum: 0 - fiatUpdate: + fiatUpdate: '2020-11-26T09:18:27.034866Z' id: 0 itemId: 1 name: Ether symbol: ETH + type: Exit + - L1Info: + ethereumBlockNum: 3 + historicLoadAmountUSD: 14099.9999859 + loadAmount: '33333333300000000000' + toForgeL1TransactionsNum: 2 + userOrigin: true + L1orL2: L1 + L2Info: + amount: '0' + batchNum: 4 + fromAccountIndex: hez:TKN1:0 + fromBJJ: hez:W6x4TZOAZ9mAqdOb3Xm_hKDLspaXfEfMMN4tXOkinS-W + fromHezEthereumAddress: hez:0x7E5F4552091A69125d5DfCb7b8C2659029395Bdf + historicUSD: + id: '0x000000000000000002000000' + itemId: 9 + position: 0 + timestamp: '2020-11-26T09:18:40.004749Z' + toAccountIndex: hez:TKN1:0 + toBJJ: + toHezEthereumAddress: + token: + USD: 423 + decimals: 18 + ethereumAddress: '0x0000000000000000000000000000000000000064' + ethereumBlockNum: 2 + fiatUpdate: '2020-11-26T09:18:27.04357Z' + id: 1 + itemId: 2 + name: Test Token 1 + symbol: TKN1 type: CreateAccountDeposit - pendingItems: 38 + - L1Info: + L1orL2: L2 + L2Info: + fee: 2 + historicFeeUSD: 3.87833366166246e-17 + nonce: 1 + amount: '11111100000000000' + batchNum: 7 + fromAccountIndex: hez:TKN1:261 + fromBJJ: hez:W6x4TZOAZ9mAqdOb3Xm_hKDLspaXfEfMMN4tXOkinS-W + fromHezEthereumAddress: hez:0x7E5F4552091A69125d5DfCb7b8C2659029395Bdf + historicUSD: 4.6999953 + id: '0x020000000001050000000001' + itemId: 15 + position: 2 + timestamp: '2020-11-26T09:18:40.004749Z' + toAccountIndex: hez:TKN1:264 + toBJJ: hez:Mj_xDCjfN-y3h_4hbhEdtkqnz6LFF1Cf4AV_8IoQswwh + toHezEthereumAddress: hez:0x2B5AD5c4795c026514f8317c7a215E218DcCD6cF + token: + USD: 423 + decimals: 18 + ethereumAddress: '0x0000000000000000000000000000000000000064' + ethereumBlockNum: 2 + fiatUpdate: '2020-11-26T09:18:27.04357Z' + id: 1 + itemId: 2 + name: Test Token 1 + symbol: TKN1 + type: Transfer + pendingItems: 23 required: - transactions - pendingItems @@ -2335,22 +2427,37 @@ components: token: $ref: '#/components/schemas/Token' example: - accountIndex: hez:SCC:256 - balance: '2560000000' - bjj: hez:m9UXbJElX5OzHMM0IxgD3Qzhx2RJw18o-tiw8s1lnwx4 - hezEthereumAddress: hez:0x00000000000000000000000000000000004Ab84F - itemId: 1 - nonce: 0 - token: - USD: 3478.93 - decimals: 7 - ethereumAddress: '0x0000000000000000000000000000000000000006' - ethereumBlockNum: 2 - fiatUpdate: - id: 6 - itemId: 7 - name: Some Cool Coin - symbol: 'SCC' + exits: + - accountIndex: hez:ETH:259 + balance: '66666600000000000' + batchNum: 8 + delayedWithdrawRequest: + delayedWithdrawn: + instantWithdrawn: + itemId: 1 + merkleProof: + Fnc: 0 + IsOld0: true + Key: '256' + OldKey: '256' + OldValue: '256' + Root: '256' + Siblings: + - '0' + - '1' + - '2' + Value: '256' + token: + USD: 500 + decimals: 18 + ethereumAddress: '0x0000000000000000000000000000000000000000' + ethereumBlockNum: 0 + fiatUpdate: '2020-11-26T09:57:29.110879Z' + id: 0 + itemId: 1 + name: Ether + symbol: ETH + pendingItems: 0 additionalProperties: false required: - itemId @@ -2372,55 +2479,39 @@ components: $ref: '#/components/schemas/PendingItems' example: accounts: - - accountIndex: hez:SCC:256 - balance: '2560000000' - bjj: hez:m9UXbJElX5OzHMM0IxgD3Qzhx2RJw18o-tiw8s1lnwx4 - hezEthereumAddress: hez:0x00000000000000000000000000000000004Ab84F - itemId: 1 + - accountIndex: hez:ETH:259 + balance: '2590000000' + bjj: hez:W6x4TZOAZ9mAqdOb3Xm_hKDLspaXfEfMMN4tXOkinS-W + hezEthereumAddress: hez:0x7E5F4552091A69125d5DfCb7b8C2659029395Bdf + itemId: 4 nonce: 0 token: - USD: 53.92 - decimals: 7 - ethereumAddress: '0x0000000000000000000000000000000000000006' - ethereumBlockNum: 2 - fiatUpdate: - id: 6 - itemId: 7 - name: Some Cool Coin - symbol: 'SCC' - - accountIndex: hez:ACC:257 - balance: '2570000000' - bjj: hez:m9UXbJElX5OzHMM0IxgD3Qzhx2RJw18o-tiw8s1lnwx4 - hezEthereumAddress: hez:0x00000000000000000000000000000000004Ab84F - itemId: 2 - nonce: 0 - token: - USD: 8.641969 - decimals: 8 - ethereumAddress: '0x0000000000000000000000000000000000000007' - ethereumBlockNum: 3 - fiatUpdate: '2020-11-17T13:28:11.016998Z' - id: 7 - itemId: 8 - name: Another Cool Coin - symbol: 'ACC' - - accountIndex: hez:VGC:258 - balance: '2580000000' - bjj: hez:m9UXbJElX5OzHMM0IxgD3Qzhx2RJw18o-tiw8s1lnwx4 - hezEthereumAddress: hez:0x00000000000000000000000000000000004Ab84F - itemId: 3 + USD: 500 + decimals: 18 + ethereumAddress: '0x0000000000000000000000000000000000000000' + ethereumBlockNum: 0 + fiatUpdate: '2020-11-26T09:53:47.444444Z' + id: 0 + itemId: 1 + name: Ether + symbol: ETH + - accountIndex: hez:TKN1:261 + balance: '2610000000' + bjj: hez:W6x4TZOAZ9mAqdOb3Xm_hKDLspaXfEfMMN4tXOkinS-W + hezEthereumAddress: hez:0x7E5F4552091A69125d5DfCb7b8C2659029395Bdf + itemId: 6 nonce: 0 token: - USD: 2349.12 - decimals: 9 - ethereumAddress: '0x0000000000000000000000000000000000000008' - ethereumBlockNum: 4 - fiatUpdate: - id: 8 - itemId: 9 - name: Vitalik the Great Coin - symbol: 'VGC' - pendingItems: 1 + USD: 423 + decimals: 18 + ethereumAddress: '0x0000000000000000000000000000000000000064' + ethereumBlockNum: 2 + fiatUpdate: '2020-11-26T09:53:47.456619Z' + id: 1 + itemId: 2 + name: Test Token 1 + symbol: TKN1 + pendingItems: 0 additionalProperties: false required: - accounts diff --git a/api/token_test.go b/api/token_test.go index 7d8aff6..ce82811 100644 --- a/api/token_test.go +++ b/api/token_test.go @@ -93,7 +93,8 @@ func TestGetTokens(t *testing.T) { // Get by name fetchedTokens = []historydb.TokenWithUSD{} limit = 5 - stringName := tc.tokens[8].Name[4:5] + tokenNameLen := len(tc.tokens[8].Name) + stringName := tc.tokens[8].Name[tokenNameLen-1:] path = fmt.Sprintf( "%s?name=%s&limit=%d&fromItem=", endpoint, stringName, limit, diff --git a/api/txshistory_test.go b/api/txshistory_test.go index 207bcc9..d67922c 100644 --- a/api/txshistory_test.go +++ b/api/txshistory_test.go @@ -255,7 +255,7 @@ func TestGetHistoryTxs(t *testing.T) { } } // Get all (no filters) - limit := 8 + limit := 20 path := fmt.Sprintf("%s?limit=%d&fromItem=", endpoint, limit) err := doGoodReqPaginated(path, historydb.OrderAsc, &testTxsResponse{}, appendIter) assert.NoError(t, err)