Stop using stateDB in API
@@ -4,10 +4,7 @@ import (
"net/http" "github.com/gin-gonic/gin" - "github.com/hermeznetwork/hermez-node/apitypes" "github.com/hermeznetwork/hermez-node/db/historydb" - "github.com/hermeznetwork/hermez-node/db/statedb" - "github.com/hermeznetwork/tracerr" ) func (a *API) getAccount(c *gin.Context) {@@ -23,16 +20,6 @@ retSQLErr(err, c)
return } - // Get balance from stateDB - account, err := a.s.LastGetAccount(*idx) - if err != nil { - retSQLErr(err, c) - return - } - - apiAccount.Balance = apitypes.NewBigIntStr(account.Balance) - apiAccount.Nonce = account.Nonce - c.JSON(http.StatusOK, apiAccount) }@@ -53,26 +40,6 @@
// Fetch Accounts from historyDB apiAccounts, pendingItems, err := a.h.GetAccountsAPI(tokenIDs, addr, bjj, fromItem, limit, order) if err != nil { - retSQLErr(err, c) - return - } - - // Get balances from stateDB - if err := a.s.LastRead(func(sdb *statedb.Last) error { - for x, apiAccount := range apiAccounts { - idx, err := stringToIdx(string(apiAccount.Idx), "Account Idx") - if err != nil { - return tracerr.Wrap(err) - } - account, err := sdb.GetAccount(*idx) - if err != nil { - return tracerr.Wrap(err) - } - apiAccounts[x].Balance = apitypes.NewBigIntStr(account.Balance) - apiAccounts[x].Nonce = account.Nonce - } - return nil - }); err != nil { retSQLErr(err, c) return }
@@ -9,7 +9,6 @@ "github.com/gin-gonic/gin"
"github.com/hermeznetwork/hermez-node/common" "github.com/hermeznetwork/hermez-node/db/historydb" "github.com/hermeznetwork/hermez-node/db/l2db" - "github.com/hermeznetwork/hermez-node/db/statedb" "github.com/hermeznetwork/tracerr" )@@ -34,7 +33,6 @@ // API serves HTTP requests to allow external interaction with the Hermez node
type API struct { h *historydb.HistoryDB cg *configAPI - s *statedb.StateDB l2 *l2db.L2DB status Status chainID uint16@@ -46,7 +44,6 @@ func NewAPI(
coordinatorEndpoints, explorerEndpoints bool, server *gin.Engine, hdb *historydb.HistoryDB, - sdb *statedb.StateDB, l2db *l2db.L2DB, config *Config, ) (*API, error) {@@ -66,7 +63,6 @@ RollupConstants: *newRollupConstants(config.RollupConstants),
AuctionConstants: config.AuctionConstants, WDelayerConstants: config.WDelayerConstants, }, - s: sdb, l2: l2db, status: Status{}, chainID: config.ChainID,
@@ -22,7 +22,6 @@ "github.com/hermeznetwork/hermez-node/common"
"github.com/hermeznetwork/hermez-node/db" "github.com/hermeznetwork/hermez-node/db/historydb" "github.com/hermeznetwork/hermez-node/db/l2db" - "github.com/hermeznetwork/hermez-node/db/statedb" "github.com/hermeznetwork/hermez-node/log" "github.com/hermeznetwork/hermez-node/test" "github.com/hermeznetwork/hermez-node/test/til"@@ -216,10 +215,6 @@ if err := os.RemoveAll(dir); err != nil {
panic(err) } }() - sdb, err := statedb.NewStateDB(statedb.Config{Path: dir, Keep: 128, Type: statedb.TypeTxSelector, NLevels: 0}) - if err != nil { - panic(err) - } // L2DB l2DB := l2db.NewL2DB(database, 10, 1000, 24*time.Hour, apiConnCon) test.WipeDB(l2DB.DB()) // this will clean HistoryDB and L2DB@@ -239,7 +234,6 @@ true,
true, apiGin, hdb, - sdb, l2DB, &_config, )@@ -350,19 +344,6 @@ commonL1Txs = append(commonL1Txs, batch.L1CoordinatorTxs...)
} } - // lastBlockNum2 := blocksData[len(blocksData)-1].Block.EthBlockNum - - // Add accounts to StateDB - for i := 0; i < len(commonAccounts); i++ { - if _, err := api.s.CreateAccount(commonAccounts[i].Idx, &commonAccounts[i]); err != nil { - panic(err) - } - } - // Make a checkpoint to make the accounts available in Last - if err := api.s.MakeCheckpoint(); err != nil { - panic(err) - } - // Generate Coordinators and add them to HistoryDB const nCoords = 10 commonCoords := test.GenCoordinators(nCoords, commonBlocks)@@ -529,13 +510,41 @@ testExits := genTestExits(commonExitTree, testTokens, commonAccounts)
testTxs := genTestTxs(commonL1Txs, commonL2Txs, commonAccounts, testTokens, commonBlocks) testBatches, testFullBatches := genTestBatches(commonBlocks, commonBatches, testTxs) poolTxsToSend, poolTxsToReceive := genTestPoolTxs(commonPoolTxs, testTokens, commonAccounts) + // Add balance and nonce to historyDB + accounts := genTestAccounts(commonAccounts, testTokens) + accUpdates := []common.AccountUpdate{} + for i := 0; i < len(accounts); i++ { + balance := new(big.Int) + balance.SetString(string(*accounts[i].Balance), 10) + idx, err := stringToIdx(string(accounts[i].Idx), "foo") + if err != nil { + panic(err) + } + accUpdates = append(accUpdates, common.AccountUpdate{ + EthBlockNum: 0, + BatchNum: 1, + Idx: *idx, + Nonce: 0, + Balance: balance, + }) + accUpdates = append(accUpdates, common.AccountUpdate{ + EthBlockNum: 0, + BatchNum: 1, + Idx: *idx, + Nonce: accounts[i].Nonce, + Balance: balance, + }) + } + if err := api.h.AddAccountUpdates(accUpdates); err != nil { + panic(err) + } tc = testCommon{ blocks: commonBlocks, tokens: testTokens, batches: testBatches, fullBatches: testFullBatches, coordinators: testCoords, - accounts: genTestAccounts(commonAccounts, testTokens), + accounts: accounts, txs: testTxs, exits: testExits, poolTxsToSend: poolTxsToSend,@@ -612,7 +621,6 @@ true,
true, apiGinTO, hdbTO, - nil, l2DBTO, &_config, )
@@ -170,13 +170,13 @@ _, err := common.NewPoolL2Tx(&poolTx)
if err != nil { return tracerr.Wrap(err) } - // Get public key - account, err := a.s.LastGetAccount(poolTx.FromIdx) + // Validate feeAmount + _, err = common.CalcFeeAmount(poolTx.Amount, poolTx.Fee) if err != nil { return tracerr.Wrap(err) } - // Validate feeAmount - _, err = common.CalcFeeAmount(poolTx.Amount, poolTx.Fee) + // Get public key + account, err := a.h.GetCommonAccountAPI(poolTx.FromIdx) if err != nil { return tracerr.Wrap(err) }
@@ -32,7 +32,6 @@
[Synchronizer] SyncLoopInterval = "1s" StatsRefreshPeriod = "1s" -StoreAccountUpdates = true [SmartContracts] Rollup = "0x8EEaea23686c319133a7cC110b840d1591d9AeE0"
@@ -236,11 +236,6 @@ // synchronizer state Eth parameters (`Eth.LastBlock` and
// `Eth.LastBatch`). This value only affects the reported % of // synchronization of blocks and batches, nothing else. StatsRefreshPeriod Duration `validate:"required"` - // StoreAccountUpdates when set to true makes the synchronizer - // store every account update in the account_update SQL table. - // This allows querying nonces and balances from the HistoryDB - // via SQL. - StoreAccountUpdates bool } `validate:"required"` SmartContracts struct { // Rollup is the address of the Hermez.sol smart contract
@@ -833,10 +833,18 @@ }
defer hdb.apiConnCon.Release() account := &AccountAPI{} err = meddler.QueryRow(hdb.db, account, `SELECT account.item_id, hez_idx(account.idx, - token.symbol) as idx, account.batch_num, account.bjj, account.eth_addr, - token.token_id, token.item_id AS token_item_id, token.eth_block_num AS token_block, - token.eth_addr as token_eth_addr, token.name, token.symbol, token.decimals, token.usd, token.usd_update - FROM account INNER JOIN token ON account.token_id = token.token_id WHERE idx = $1;`, idx) + token.symbol) as idx, account.batch_num, account.bjj, account.eth_addr, + token.token_id, token.item_id AS token_item_id, token.eth_block_num AS token_block, + token.eth_addr as token_eth_addr, token.name, token.symbol, token.decimals, token.usd, + token.usd_update, account_update.nonce, account_update.balance + FROM account inner JOIN ( + SELECT idx, nonce, balance + FROM account_update + WHERE idx = $1 + ORDER BY item_id DESC LIMIT 1 + ) AS account_update ON account_update.idx = account.idx + INNER JOIN token ON account.token_id = token.token_id + WHERE account.idx = $1;`, idx) if err != nil { return nil, tracerr.Wrap(err)@@ -864,8 +872,13 @@ var args []interface{}
queryStr := `SELECT account.item_id, hez_idx(account.idx, token.symbol) as idx, account.batch_num, account.bjj, account.eth_addr, token.token_id, token.item_id AS token_item_id, token.eth_block_num AS token_block, token.eth_addr as token_eth_addr, token.name, token.symbol, token.decimals, token.usd, token.usd_update, - COUNT(*) OVER() AS total_items - FROM account INNER JOIN token ON account.token_id = token.token_id ` + account_update.nonce, account_update.balance, COUNT(*) OVER() AS total_items + FROM account inner JOIN ( + SELECT DISTINCT idx, + first_value(nonce) over(partition by idx ORDER BY item_id DESC) as nonce, + first_value(balance) over(partition by idx ORDER BY item_id DESC) as balance + FROM account_update + ) AS account_update ON account_update.idx = account.idx INNER JOIN token ON account.token_id = token.token_id ` // Apply filters nextIsAnd := false // ethAddr filter@@ -1024,3 +1037,18 @@ }
return avgTransactionFee, nil } + +// GetCommonAccountAPI returns the account associated to an account idx +func (hdb *HistoryDB) GetCommonAccountAPI(idx common.Idx) (*common.Account, error) { + cancel, err := hdb.apiConnCon.Acquire() + defer cancel() + if err != nil { + return nil, tracerr.Wrap(err) + } + defer hdb.apiConnCon.Release() + account := &common.Account{} + err = meddler.QueryRow( + hdb.db, account, `SELECT * FROM account WHERE idx = $1;`, idx, + ) + return account, tracerr.Wrap(err) +}
@@ -239,8 +239,8 @@ Idx apitypes.HezIdx `meddler:"idx"`
BatchNum common.BatchNum `meddler:"batch_num"` PublicKey apitypes.HezBJJ `meddler:"bjj"` EthAddr apitypes.HezEthAddr `meddler:"eth_addr"` - Nonce common.Nonce `meddler:"-"` // max of 40 bits used - Balance *apitypes.BigIntStr `meddler:"-"` // max of 192 bits used + Nonce common.Nonce `meddler:"nonce"` // max of 40 bits used + Balance *apitypes.BigIntStr `meddler:"balance"` // max of 192 bits used TotalItems uint64 `meddler:"total_items"` FirstItem uint64 `meddler:"first_item"` LastItem uint64 `meddler:"last_item"`
@@ -662,35 +662,35 @@ timestamp TIMESTAMP WITHOUT TIME ZONE NOT NULL DEFAULT timezone('utc', now())
); -- +migrate Down --- drop triggers -DROP TRIGGER trigger_token_usd_update ON token; -DROP TRIGGER trigger_set_tx ON tx; -DROP TRIGGER trigger_forge_l1_txs ON batch; -DROP TRIGGER trigger_set_pool_tx ON tx_pool; --- drop functions -DROP FUNCTION hez_idx; -DROP FUNCTION set_token_usd_update; -DROP FUNCTION fee_percentage; -DROP FUNCTION set_tx; -DROP FUNCTION forge_l1_user_txs; -DROP FUNCTION set_pool_tx; --- drop tables -DROP TABLE account_creation_auth; -DROP TABLE tx_pool; -DROP TABLE auction_vars; -DROP TABLE rollup_vars; -DROP TABLE escape_hatch_withdrawal; -DROP TABLE bucket_update; -DROP TABLE token_exchange; -DROP TABLE wdelayer_vars; -DROP TABLE tx; -DROP TABLE exit_tree; -DROP TABLE account_update; -DROP TABLE account; -DROP TABLE token; -DROP TABLE bid; -DROP TABLE batch; -DROP TABLE coordinator; -DROP TABLE block; --- drop sequences -DROP SEQUENCE tx_item_id; +-- triggers +DROP TRIGGER IF EXISTS trigger_token_usd_update ON token; +DROP TRIGGER IF EXISTS trigger_set_tx ON tx; +DROP TRIGGER IF EXISTS trigger_forge_l1_txs ON batch; +DROP TRIGGER IF EXISTS trigger_set_pool_tx ON tx_pool; +-- functions +DROP FUNCTION IF EXISTS hez_idx; +DROP FUNCTION IF EXISTS set_token_usd_update; +DROP FUNCTION IF EXISTS fee_percentage; +DROP FUNCTION IF EXISTS set_tx; +DROP FUNCTION IF EXISTS forge_l1_user_txs; +DROP FUNCTION IF EXISTS set_pool_tx; +-- drop tables IF EXISTS +DROP TABLE IF EXISTS account_creation_auth; +DROP TABLE IF EXISTS tx_pool; +DROP TABLE IF EXISTS auction_vars; +DROP TABLE IF EXISTS rollup_vars; +DROP TABLE IF EXISTS escape_hatch_withdrawal; +DROP TABLE IF EXISTS bucket_update; +DROP TABLE IF EXISTS token_exchange; +DROP TABLE IF EXISTS wdelayer_vars; +DROP TABLE IF EXISTS tx; +DROP TABLE IF EXISTS exit_tree; +DROP TABLE IF EXISTS account_update; +DROP TABLE IF EXISTS account; +DROP TABLE IF EXISTS token; +DROP TABLE IF EXISTS bid; +DROP TABLE IF EXISTS batch; +DROP TABLE IF EXISTS coordinator; +DROP TABLE IF EXISTS block; +-- sequences +DROP SEQUENCE IF EXISTS tx_item_id;
@@ -183,9 +183,8 @@ return nil, tracerr.Wrap(err)
} sync, err := synchronizer.NewSynchronizer(client, historyDB, stateDB, synchronizer.Config{ - StatsRefreshPeriod: cfg.Synchronizer.StatsRefreshPeriod.Duration, - StoreAccountUpdates: cfg.Synchronizer.StoreAccountUpdates, - ChainID: chainIDU16, + StatsRefreshPeriod: cfg.Synchronizer.StatsRefreshPeriod.Duration, + ChainID: chainIDU16, }) if err != nil { return nil, tracerr.Wrap(err)@@ -430,7 +429,6 @@ _api, err := api.NewAPI(
coordinatorEndpoints, explorerEndpoints, engine, hdb, - sdb, l2db, config, )
@@ -206,9 +206,8 @@ }
// Config is the Synchronizer configuration type Config struct { - StatsRefreshPeriod time.Duration - StoreAccountUpdates bool - ChainID uint16 + StatsRefreshPeriod time.Duration + ChainID uint16 } // Synchronizer implements the Synchronizer type@@ -994,19 +993,17 @@ createdAccount.BatchNum = batchNum
} batchData.CreatedAccounts = processTxsOut.CreatedAccounts - if s.cfg.StoreAccountUpdates { - batchData.UpdatedAccounts = make([]common.AccountUpdate, 0, - len(processTxsOut.UpdatedAccounts)) - for _, acc := range processTxsOut.UpdatedAccounts { - batchData.UpdatedAccounts = append(batchData.UpdatedAccounts, - common.AccountUpdate{ - EthBlockNum: blockNum, - BatchNum: batchNum, - Idx: acc.Idx, - Nonce: acc.Nonce, - Balance: acc.Balance, - }) - } + batchData.UpdatedAccounts = make([]common.AccountUpdate, 0, + len(processTxsOut.UpdatedAccounts)) + for _, acc := range processTxsOut.UpdatedAccounts { + batchData.UpdatedAccounts = append(batchData.UpdatedAccounts, + common.AccountUpdate{ + EthBlockNum: blockNum, + BatchNum: batchNum, + Idx: acc.Idx, + Nonce: acc.Nonce, + Balance: acc.Balance, + }) } slotNum := int64(0)
@@ -346,8 +346,7 @@ client := test.NewClient(true, &timer, ðCommon.Address{}, clientSetup)
// Create Synchronizer s, err := NewSynchronizer(client, historyDB, stateDB, Config{ - StatsRefreshPeriod: 0 * time.Second, - StoreAccountUpdates: true, + StatsRefreshPeriod: 0 * time.Second, }) require.NoError(t, err)@@ -738,8 +737,7 @@ client := test.NewClient(true, &timer, ðCommon.Address{}, clientSetup)
// Create Synchronizer s, err := NewSynchronizer(client, historyDB, stateDB, Config{ - StatsRefreshPeriod: 0 * time.Second, - StoreAccountUpdates: true, + StatsRefreshPeriod: 0 * time.Second, }) require.NoError(t, err)@@ -839,8 +837,7 @@ require.True(t, stats.Synced())
syncCommitment[syncBlock.Block.Num] = stats.Sync.Auction.CurrentSlot.ForgerCommitment s2, err := NewSynchronizer(client, historyDB, stateDB, Config{ - StatsRefreshPeriod: 0 * time.Second, - StoreAccountUpdates: true, + StatsRefreshPeriod: 0 * time.Second, }) require.NoError(t, err) stats = s2.Stats()