arnaucube
arnaucube/hermez-nodePublic Self-hosted repository
Helper methods for Synchronizer and TX refactor
ToniRamirezM toni@iden3.com
Thu, 17 Sep 2020 13:17:26 +0200
commit

ac677694fea7289d517b1b6e8d997885a12fa2da

parent

c0336f485f57ee5baa03814c1c1e2492a2ebcb7b

M .github/workflows/test.yml → .github/workflows/test.yml

@@ -23,4 +23,4 @@ env:

POSTGRES_PASS: ${{ secrets.POSTGRES_PASS }} ETHCLIENT_DIAL_URL: ${{ secrets.ETHCLIENT_DIAL_URL }} GOARCH: ${{ matrix.goarch }} - run: go test ./... -v + run: go test -p 1 ./...
M README.md → README.md

@@ -13,8 +13,12 @@

- Then, run the tests with the password as env var ``` -POSTGRES_PASS=yourpasswordhere ETHCLIENT_DIAL_URL=yourethereumurlhere go test ./... +POSTGRES_PASS=yourpasswordhere ETHCLIENT_DIAL_URL=yourethereumurlhere go test -p 1 ./... ``` + +NOTE: `-p 1` forces execution of package test in serial. Otherwise they may be +executed in paralel and the test may find unexpected entries in the SQL +databse because it's shared among all tests. ## Lint
M api/api_test.go → api/api_test.go

@@ -82,6 +82,11 @@ hdb, err := historydb.NewHistoryDB(5432, "localhost", "hermez", pass, "history")

if err != nil { panic(err) } + // Reset DB + err = hdb.Reorg(-1) + if err != nil { + panic(err) + } dir, err := ioutil.TempDir("", "tmpdb") if err != nil { panic(err)

@@ -94,6 +99,7 @@ l2db, err := l2db.NewL2DB(5432, "localhost", "hermez", pass, "l2", 10, 512, 24*time.Hour)

if err != nil { panic(err) } + test.CleanL2DB(l2db.DB()) // Init API api := gin.Default() if err := SetAPIEndpoints(
M common/batch.go → common/batch.go

@@ -8,7 +8,7 @@

ethCommon "github.com/ethereum/go-ethereum/common" ) -const batchNumBytesLen = 4 +const batchNumBytesLen = 8 // Batch is a struct that represents Hermez network batch type Batch struct {

@@ -24,20 +24,20 @@ SlotNum SlotNum `meddler:"slot_num"` // Slot in which the batch is forged

} // BatchNum identifies a batch -type BatchNum uint32 +type BatchNum int64 // Bytes returns a byte array of length 4 representing the BatchNum func (bn BatchNum) Bytes() []byte { - var batchNumBytes [4]byte - binary.LittleEndian.PutUint32(batchNumBytes[:], uint32(bn)) + var batchNumBytes [batchNumBytesLen]byte + binary.BigEndian.PutUint64(batchNumBytes[:], uint64(bn)) return batchNumBytes[:] } // BatchNumFromBytes returns BatchNum from a []byte func BatchNumFromBytes(b []byte) (BatchNum, error) { if len(b) != batchNumBytesLen { - return 0, fmt.Errorf("can not parse BatchNumFromBytes, bytes len %d, expected 4", len(b)) + return 0, fmt.Errorf("can not parse BatchNumFromBytes, bytes len %d, expected %d", len(b), batchNumBytesLen) } - batchNum := binary.LittleEndian.Uint32(b[:4]) + batchNum := binary.BigEndian.Uint64(b[:batchNumBytesLen]) return BatchNum(batchNum), nil }
M common/coordinator.go → common/coordinator.go

@@ -7,8 +7,8 @@

// Coordinator represents a Hermez network coordinator who wins an auction for an specific slot // WARNING: this is strongly based on the previous implementation, once the new spec is done, this may change a lot. type Coordinator struct { - EthBlockNum int64 // block in which the coordinator was registered - Forger ethCommon.Address // address of the forger - Withdraw ethCommon.Address // address of the withdraw - URL string // URL of the coordinators API + Forger ethCommon.Address `meddler:"forger_addr"` // address of the forger + EthBlockNum int64 `meddler:"eth_block_num"` // block in which the coordinator was registered + WithdrawAddr ethCommon.Address `meddler:"withdraw_addr"` // address of the withdraw + URL string `meddler:"url"` // URL of the coordinators API }
M common/exittree.go → common/exittree.go

@@ -8,8 +8,19 @@ )

// ExitInfo represents the ExitTree Leaf data type ExitInfo struct { - AccountIdx Idx - MerkleProof *merkletree.CircomVerifierProof - Balance *big.Int - Nullifier *big.Int + BatchNum BatchNum `meddler:"batch_num"` + AccountIdx Idx `meddler:"account_idx"` + MerkleProof *merkletree.CircomVerifierProof `meddler:"merkle_proof,json"` + Balance *big.Int `meddler:"balance,bigint"` + // InstantWithdrawn is the ethBlockNum in which the exit is withdrawn + // instantly. nil means this hasn't happened. + InstantWithdrawn *int64 `meddler:"instant_withdrawn"` + // DelayedWithdrawRequest is the ethBlockNum in which the exit is + // requested to be withdrawn from the delayedWithdrawn smart contract. + // nil means this hasn't happened. + DelayedWithdrawRequest *int64 `meddler:"delayed_withdraw_request"` + // DelayedWithdrawn is the ethBlockNum in which the exit is withdrawn + // from the delayedWithdrawn smart contract. nil means this hasn't + // happened. + DelayedWithdrawn *int64 `meddler:"delayed_withdrawn"` }
M common/tx.go → common/tx.go

@@ -66,3 +66,24 @@ Fee FeeSelector `meddler:"fee,zeroisnull"`

FeeUSD float64 `meddler:"fee_usd,zeroisnull"` Nonce Nonce `meddler:"nonce,zeroisnull"` } + +// L1Tx returns a *L1Tx from the Tx +func (tx *Tx) L1Tx() *L1Tx { + l1Tx := &L1Tx{ + TxID: tx.TxID, + ToForgeL1TxsNum: tx.ToForgeL1TxsNum, + Position: tx.Position, + UserOrigin: tx.UserOrigin, + FromIdx: tx.FromIdx, + FromEthAddr: tx.FromEthAddr, + FromBJJ: tx.FromBJJ, + ToIdx: tx.ToIdx, + TokenID: tx.TokenID, + Amount: tx.Amount, + LoadAmount: tx.LoadAmount, + EthBlockNum: tx.EthBlockNum, + Type: tx.Type, + BatchNum: tx.BatchNum, + } + return l1Tx +}
M db/historydb/historydb.go → db/historydb/historydb.go

@@ -26,6 +26,36 @@ type HistoryDB struct {

db *sqlx.DB } +// BlockData contains the information of a Block +type BlockData struct { + block *common.Block + // Rollup + // L1UserTxs that were submitted in the block + L1UserTxs []common.L1Tx + Batches []BatchData + RegisteredTokens []common.Token + RollupVars *common.RollupVars + // Auction + Bids []common.Bid + Coordinators []common.Coordinator + AuctionVars *common.AuctionVars + // WithdrawalDelayer + // TODO: enable when common.WithdrawalDelayerVars is Merged from Synchronizer PR + // WithdrawalDelayerVars *common.WithdrawalDelayerVars +} + +// BatchData contains the information of a Batch +type BatchData struct { + // L1UserTxs that were forged in the batch + L1Batch bool // TODO: Remove once Batch.ForgeL1TxsNum is a pointer + L1UserTxs []common.L1Tx + L1CoordinatorTxs []common.L1Tx + L2Txs []common.L2Tx + CreatedAccounts []common.Account + ExitTree []common.ExitInfo + Batch *common.Batch +} + // NewHistoryDB initialize the DB func NewHistoryDB(port int, host, user, password, dbname string) (*HistoryDB, error) { // Connect to DB

@@ -52,14 +82,19 @@ return &HistoryDB{hdb}, nil

} // AddBlock insert a block into the DB -func (hdb *HistoryDB) AddBlock(block *common.Block) error { - return meddler.Insert(hdb.db, "block", block) +func (hdb *HistoryDB) AddBlock(block *common.Block) error { return hdb.addBlock(hdb.db, block) } +func (hdb *HistoryDB) addBlock(d meddler.DB, block *common.Block) error { + return meddler.Insert(d, "block", block) } // AddBlocks inserts blocks into the DB func (hdb *HistoryDB) AddBlocks(blocks []common.Block) error { + return hdb.addBlocks(hdb.db, blocks) +} + +func (hdb *HistoryDB) addBlocks(d meddler.DB, blocks []common.Block) error { return db.BulkInsert( - hdb.db, + d, `INSERT INTO block ( eth_block_num, timestamp,

@@ -84,7 +119,7 @@ func (hdb *HistoryDB) GetBlocks(from, to int64) ([]*common.Block, error) {

var blocks []*common.Block err := meddler.QueryAll( hdb.db, &blocks, - "SELECT * FROM block WHERE $1 <= eth_block_num AND eth_block_num < $2", + "SELECT * FROM block WHERE $1 <= eth_block_num AND eth_block_num < $2;", from, to, ) return blocks, err

@@ -99,10 +134,19 @@ )

return block, err } +// AddBatch insert a Batch into the DB +func (hdb *HistoryDB) AddBatch(batch *common.Batch) error { return hdb.addBatch(hdb.db, batch) } +func (hdb *HistoryDB) addBatch(d meddler.DB, batch *common.Batch) error { + return meddler.Insert(d, "batch", batch) +} + // AddBatches insert Bids into the DB func (hdb *HistoryDB) AddBatches(batches []common.Batch) error { + return hdb.addBatches(hdb.db, batches) +} +func (hdb *HistoryDB) addBatches(d meddler.DB, batches []common.Batch) error { return db.BulkInsert( - hdb.db, + d, `INSERT INTO batch ( batch_num, eth_block_num,

@@ -123,7 +167,7 @@ func (hdb *HistoryDB) GetBatches(from, to common.BatchNum) ([]*common.Batch, error) {

var batches []*common.Batch err := meddler.QueryAll( hdb.db, &batches, - "SELECT * FROM batch WHERE $1 <= batch_num AND batch_num < $2", + "SELECT * FROM batch WHERE $1 <= batch_num AND batch_num < $2;", from, to, ) return batches, err

@@ -144,29 +188,17 @@ lastL1TxsNum := new(int64)

return lastL1TxsNum, row.Scan(&lastL1TxsNum) } -// Reorg deletes all the information that was added into the DB after the lastValidBlock +// Reorg deletes all the information that was added into the DB after the +// lastValidBlock. If lastValidBlock is negative, all block information is +// deleted. func (hdb *HistoryDB) Reorg(lastValidBlock int64) error { - _, err := hdb.db.Exec("DELETE FROM block WHERE eth_block_num > $1;", lastValidBlock) - return err -} - -// SyncRollup stores all the data that can be changed / added on a block in the Rollup SC -func (hdb *HistoryDB) SyncRollup( - blockNum uint64, - l1txs []common.L1Tx, - l2txs []common.L2Tx, - registeredAccounts []common.Account, - exitTree common.ExitInfo, - withdrawals common.ExitInfo, - registeredTokens []common.Token, - batches []common.Batch, - vars *common.RollupVars, -) error { - // TODO: make all in a single DB commit - if err := hdb.AddBatches(batches); err != nil { - return err + var err error + if lastValidBlock < 0 { + _, err = hdb.db.Exec("DELETE FROM block;") + } else { + _, err = hdb.db.Exec("DELETE FROM block WHERE eth_block_num > $1;", lastValidBlock) } - return nil + return err } // SyncPoD stores all the data that can be changed / added on a block in the PoD SC

@@ -179,12 +211,13 @@ ) error {

return nil } -// addBids insert Bids into the DB -func (hdb *HistoryDB) addBids(bids []common.Bid) error { +// AddBids insert Bids into the DB +func (hdb *HistoryDB) AddBids(bids []common.Bid) error { return hdb.addBids(hdb.db, bids) } +func (hdb *HistoryDB) addBids(d meddler.DB, bids []common.Bid) error { // TODO: check the coordinator info return db.BulkInsert( - hdb.db, - "INSERT INTO bid (slot_num, forger_addr, bid_value, eth_block_num) VALUES %s", + d, + "INSERT INTO bid (slot_num, forger_addr, bid_value, eth_block_num) VALUES %s;", bids[:], ) }

@@ -199,15 +232,41 @@ )

return bids, err } +// AddCoordinators insert Coordinators into the DB +func (hdb *HistoryDB) AddCoordinators(coordinators []common.Coordinator) error { + return hdb.addCoordinators(hdb.db, coordinators) +} +func (hdb *HistoryDB) addCoordinators(d meddler.DB, coordinators []common.Coordinator) error { + return db.BulkInsert( + d, + "INSERT INTO coordinator (forger_addr, eth_block_num, withdraw_addr, url) VALUES %s;", + coordinators[:], + ) +} + +// AddExitTree insert Exit tree into the DB +func (hdb *HistoryDB) AddExitTree(exitTree []common.ExitInfo) error { + return hdb.addExitTree(hdb.db, exitTree) +} +func (hdb *HistoryDB) addExitTree(d meddler.DB, exitTree []common.ExitInfo) error { + return db.BulkInsert( + d, + "INSERT INTO exit_tree (batch_num, account_idx, merkle_proof, balance, "+ + "instant_withdrawn, delayed_withdraw_request, delayed_withdrawn) VALUES %s;", + exitTree[:], + ) +} + // AddToken insert a token into the DB func (hdb *HistoryDB) AddToken(token *common.Token) error { return meddler.Insert(hdb.db, "token", token) } // AddTokens insert tokens into the DB -func (hdb *HistoryDB) AddTokens(tokens []common.Token) error { +func (hdb *HistoryDB) AddTokens(tokens []common.Token) error { return hdb.addTokens(hdb.db, tokens) } +func (hdb *HistoryDB) addTokens(d meddler.DB, tokens []common.Token) error { return db.BulkInsert( - hdb.db, + d, `INSERT INTO token ( token_id, eth_block_num,

@@ -243,8 +302,11 @@ }

// AddAccounts insert accounts into the DB func (hdb *HistoryDB) AddAccounts(accounts []common.Account) error { + return hdb.addAccounts(hdb.db, accounts) +} +func (hdb *HistoryDB) addAccounts(d meddler.DB, accounts []common.Account) error { return db.BulkInsert( - hdb.db, + d, `INSERT INTO account ( idx, token_id,

@@ -267,27 +329,30 @@ return accs, err

} // AddL1Txs inserts L1 txs to the DB -func (hdb *HistoryDB) AddL1Txs(l1txs []common.L1Tx) error { +func (hdb *HistoryDB) AddL1Txs(l1txs []common.L1Tx) error { return hdb.addL1Txs(hdb.db, l1txs) } +func (hdb *HistoryDB) addL1Txs(d meddler.DB, l1txs []common.L1Tx) error { txs := []common.Tx{} for _, tx := range l1txs { - txs = append(txs, *tx.Tx()) + txs = append(txs, *(tx.Tx())) } - return hdb.AddTxs(txs) + return hdb.addTxs(d, txs) } // AddL2Txs inserts L2 txs to the DB -func (hdb *HistoryDB) AddL2Txs(l2txs []common.L2Tx) error { +func (hdb *HistoryDB) AddL2Txs(l2txs []common.L2Tx) error { return hdb.addL2Txs(hdb.db, l2txs) } +func (hdb *HistoryDB) addL2Txs(d meddler.DB, l2txs []common.L2Tx) error { txs := []common.Tx{} for _, tx := range l2txs { - txs = append(txs, *tx.Tx()) + txs = append(txs, *(tx.Tx())) } - return hdb.AddTxs(txs) + return hdb.addTxs(d, txs) } // AddTxs insert L1 txs into the DB -func (hdb *HistoryDB) AddTxs(txs []common.Tx) error { +func (hdb *HistoryDB) AddTxs(txs []common.Tx) error { return hdb.addTxs(hdb.db, txs) } +func (hdb *HistoryDB) addTxs(d meddler.DB, txs []common.Tx) error { return db.BulkInsert( - hdb.db, + d, `INSERT INTO tx ( is_l1, id,

@@ -314,6 +379,16 @@ nonce

) VALUES %s;`, txs[:], ) +} + +// SetBatchNumL1UserTxs sets the batchNum in all the L1UserTxs with toForgeL1TxsNum. +func (hdb *HistoryDB) SetBatchNumL1UserTxs(toForgeL1TxsNum, batchNum int64) error { + return hdb.setBatchNumL1UserTxs(hdb.db, toForgeL1TxsNum, batchNum) +} +func (hdb *HistoryDB) setBatchNumL1UserTxs(d meddler.DB, toForgeL1TxsNum, batchNum int64) error { + _, err := d.Exec("UPDATE tx SET batch_num = $1 WHERE to_forge_l1_txs_num = $2 AND is_l1 = TRUE AND user_origin = TRUE;", + batchNum, toForgeL1TxsNum) + return err } // GetTxs returns a list of txs from the DB

@@ -409,7 +484,7 @@ } else {

queryStr += "ORDER BY (batch_num, position) ASC NULLS LAST " queryStr += fmt.Sprintf("OFFSET %d ", *offset) } - queryStr += fmt.Sprintf("LIMIT %d ", *limit) + queryStr += fmt.Sprintf("LIMIT %d;", *limit) query = hdb.db.Rebind(queryStr) // log.Debug(query) txs := []*HistoryTx{}

@@ -436,6 +511,128 @@ hdb.db, tx,

"SELECT * FROM tx WHERE id = $1;", txID, ) +} + +// GetL1UserTxs gets L1 User Txs to be forged in a batch that will create an account +// TODO: This is currently not used. Figure out if it should be used somewhere or removed. +func (hdb *HistoryDB) GetL1UserTxs(toForgeL1TxsNum int64) ([]*common.Tx, error) { + var txs []*common.Tx + err := meddler.QueryAll( + hdb.db, &txs, + "SELECT * FROM tx WHERE to_forge_l1_txs_num = $1 AND is_l1 = TRUE AND user_origin = TRUE;", + toForgeL1TxsNum, + ) + return txs, err +} + +// TODO: Think about chaning all the queries that return a last value, to queries that return the next valid value. + +// GetLastTxsPosition for a given to_forge_l1_txs_num +func (hdb *HistoryDB) GetLastTxsPosition(toForgeL1TxsNum int64) (int, error) { + row := hdb.db.QueryRow("SELECT MAX(position) FROM tx WHERE to_forge_l1_txs_num = $1;", toForgeL1TxsNum) + var lastL1TxsPosition int + return lastL1TxsPosition, row.Scan(&lastL1TxsPosition) +} + +// AddBlockSCData stores all the information of a block retrieved by the Synchronizer +func (hdb *HistoryDB) AddBlockSCData(blockData *BlockData) (err error) { + txn, err := hdb.db.Begin() + if err != nil { + return err + } + defer func() { + if err != nil { + err = txn.Rollback() + } + }() + + // Add block + err = hdb.addBlock(txn, blockData.block) + if err != nil { + return err + } + + // Add l1 Txs + if len(blockData.L1UserTxs) > 0 { + err = hdb.addL1Txs(txn, blockData.L1UserTxs) + if err != nil { + return err + } + } + + // Add Tokens + if len(blockData.RegisteredTokens) > 0 { + err = hdb.addTokens(txn, blockData.RegisteredTokens) + if err != nil { + return err + } + } + + // Add Bids + if len(blockData.Bids) > 0 { + err = hdb.addBids(txn, blockData.Bids) + if err != nil { + return err + } + } + + // Add Coordinators + if len(blockData.Coordinators) > 0 { + err = hdb.addCoordinators(txn, blockData.Coordinators) + if err != nil { + return err + } + } + + // Add Batches + for _, batch := range blockData.Batches { + if batch.L1Batch { + err = hdb.setBatchNumL1UserTxs(txn, batch.Batch.ForgeL1TxsNum, int64(batch.Batch.BatchNum)) + if err != nil { + return err + } + if len(batch.L1CoordinatorTxs) > 0 { + err = hdb.addL1Txs(txn, batch.L1CoordinatorTxs) + if err != nil { + return err + } + } + } + + // Add l2 Txs + if len(batch.L2Txs) > 0 { + err = hdb.addL2Txs(txn, batch.L2Txs) + if err != nil { + return err + } + } + + // Add accounts + if len(batch.CreatedAccounts) > 0 { + err = hdb.addAccounts(txn, batch.CreatedAccounts) + if err != nil { + return err + } + } + + // Add exit tree + if len(batch.ExitTree) > 0 { + err = hdb.addExitTree(txn, batch.ExitTree) + if err != nil { + return err + } + } + + // Add Batch + err = hdb.addBatch(txn, batch.Batch) + if err != nil { + return err + } + + // TODO: INSERT CONTRACTS VARS + } + + return txn.Commit() } // Close frees the resources used by HistoryDB
M db/historydb/historydb_test.go → db/historydb/historydb_test.go

@@ -119,10 +119,12 @@ blocks := setTestBlocks(fromBlock, toBlock)

// Generate fake coordinators const nCoords = 5 coords := test.GenCoordinators(nCoords, blocks) + err := historyDB.AddCoordinators(coords) + assert.NoError(t, err) // Generate fake bids const nBids = 20 bids := test.GenBids(nBids, blocks, coords) - err := historyDB.addBids(bids) + err = historyDB.AddBids(bids) assert.NoError(t, err) // Fetch bids fetchedBids, err := historyDB.GetBids()

@@ -302,6 +304,35 @@ // nonce can't be null

l2txs[0].Nonce = 0 err = historyDB.AddL2Txs(l2txs) assert.Error(t, err) + // Test helper functions for Synchronizer + txs, err := historyDB.GetL1UserTxs(2) + assert.NoError(t, err) + assert.NotZero(t, len(txs)) + position, err := historyDB.GetLastTxsPosition(2) + assert.NoError(t, err) + assert.Equal(t, 22, position) + // Test Update L1 TX Batch_num + assert.Equal(t, common.BatchNum(0), txs[0].BatchNum) + txs[0].BatchNum = common.BatchNum(1) + // err = historyDB.UpdateTxsBatchNum(txs) + err = historyDB.SetBatchNumL1UserTxs(2, 1) + assert.NoError(t, err) + txs, err = historyDB.GetL1UserTxs(2) + assert.NoError(t, err) + assert.NotZero(t, len(txs)) + assert.Equal(t, common.BatchNum(1), txs[0].BatchNum) +} + +func TestExitTree(t *testing.T) { + nBatches := 17 + blocks := setTestBlocks(0, 10) + batches := test.GenBatches(nBatches, blocks) + err := historyDB.AddBatches(batches) + assert.NoError(t, err) + + exitTree := test.GenExitTree(nBatches) + err = historyDB.AddExitTree(exitTree) + assert.NoError(t, err) } // setTestBlocks WARNING: this will delete the blocks and recreate them

@@ -317,5 +348,5 @@ return blocks

} func cleanHistoryDB() error { - return historyDB.Reorg(0) + return historyDB.Reorg(-1) }
M db/historydb/migrations/001_init.sql → db/historydb/migrations/001_init.sql

@@ -27,11 +27,12 @@ );

CREATE TABLE exit_tree ( batch_num BIGINT REFERENCES batch (batch_num) ON DELETE CASCADE, - withdrawn BIGINT REFERENCES batch (batch_num) ON DELETE SET NULL, account_idx BIGINT, merkle_proof BYTEA NOT NULL, - balance NUMERIC NOT NULL, - nullifier BYTEA NOT NULL, + balance BYTEA NOT NULL, + instant_withdrawn BIGINT REFERENCES batch (batch_num) ON DELETE SET NULL, + delayed_withdraw_request BIGINT REFERENCES batch (batch_num) ON DELETE SET NULL, + delayed_withdrawn BIGINT REFERENCES batch (batch_num) ON DELETE SET NULL, PRIMARY KEY (batch_num, account_idx) );

@@ -205,4 +206,4 @@ DROP TABLE bid;

DROP TABLE exit_tree; DROP TABLE batch; DROP TABLE coordinator; -DROP TABLE block;+DROP TABLE block;
M db/l2db/l2db.go → db/l2db/l2db.go

@@ -173,7 +173,7 @@ }

// CheckNonces invalidate txs with nonces that are smaller or equal than their respective accounts nonces. // The state of the affected txs will be changed from Pending -> Invalid -func (l2db *L2DB) CheckNonces(updatedAccounts []common.Account, batchNum common.BatchNum) error { +func (l2db *L2DB) CheckNonces(updatedAccounts []common.Account, batchNum common.BatchNum) (err error) { txn, err := l2db.db.Begin() if err != nil { return err

@@ -203,7 +203,7 @@ return txn.Commit()

} // UpdateTxValue updates the absolute fee and value of txs given a token list that include their price in USD -func (l2db *L2DB) UpdateTxValue(tokens []common.Token) error { +func (l2db *L2DB) UpdateTxValue(tokens []common.Token) (err error) { // WARNING: this is very slow and should be optimized txn, err := l2db.db.Begin() if err != nil {

@@ -252,7 +252,7 @@ }

// Purge deletes transactions that have been forged or marked as invalid for longer than the safety period // it also deletes txs that has been in the L2DB for longer than the ttl if maxTxs has been exceeded -func (l2db *L2DB) Purge(currentBatchNum common.BatchNum) error { +func (l2db *L2DB) Purge(currentBatchNum common.BatchNum) (err error) { txn, err := l2db.db.Begin() if err != nil { return err
M db/statedb/txprocessors.go → db/statedb/txprocessors.go

@@ -8,7 +8,6 @@

"github.com/hermeznetwork/hermez-node/common" "github.com/hermeznetwork/hermez-node/log" "github.com/iden3/go-iden3-crypto/babyjub" - "github.com/iden3/go-iden3-crypto/poseidon" "github.com/iden3/go-merkletree" "github.com/iden3/go-merkletree/db" "github.com/iden3/go-merkletree/db/memory"

@@ -142,24 +141,10 @@ p, err := exitTree.GenerateCircomVerifierProof(exitIdx.BigInt(), nil)

if err != nil { return nil, nil, err } - // 1. compute nullifier - exitAccStateValue, err := exitAccount.HashValue() - if err != nil { - return nil, nil, err - } - nullifier, err := poseidon.Hash([]*big.Int{ - exitAccStateValue, - big.NewInt(int64(s.currentBatch)), - exitTree.Root().BigInt(), - }) - if err != nil { - return nil, nil, err - } - // 2. generate common.ExitInfo + // 1. generate common.ExitInfo ei := &common.ExitInfo{ AccountIdx: exitIdx, MerkleProof: p, - Nullifier: nullifier, Balance: exitAccount.Balance, } exitInfos = append(exitInfos, ei)
M synchronizer/synchronizer.go → synchronizer/synchronizer.go

@@ -501,9 +501,9 @@

// Get Coordinators for _, eNewCoordinator := range auctionEvents.NewCoordinator { coordinator := &common.Coordinator{ - Forger: eNewCoordinator.ForgerAddress, - Withdraw: eNewCoordinator.WithdrawalAddress, - URL: eNewCoordinator.URL, + Forger: eNewCoordinator.ForgerAddress, + WithdrawAddr: eNewCoordinator.WithdrawalAddress, + URL: eNewCoordinator.URL, } auctionData.coordinators = append(auctionData.coordinators, coordinator) }

@@ -525,9 +525,9 @@

// Get Coordinators from updates for _, eCoordinatorUpdated := range auctionEvents.CoordinatorUpdated { coordinator := &common.Coordinator{ - Forger: eCoordinatorUpdated.ForgerAddress, - Withdraw: eCoordinatorUpdated.WithdrawalAddress, - URL: eCoordinatorUpdated.URL, + Forger: eCoordinatorUpdated.ForgerAddress, + WithdrawAddr: eCoordinatorUpdated.WithdrawalAddress, + URL: eCoordinatorUpdated.URL, } auctionData.coordinators = append(auctionData.coordinators, coordinator) }
M test/historydb.go → test/historydb.go

@@ -10,6 +10,7 @@

ethCommon "github.com/ethereum/go-ethereum/common" "github.com/hermeznetwork/hermez-node/common" "github.com/iden3/go-iden3-crypto/babyjub" + "github.com/iden3/go-merkletree" ) // WARNING: the generators in this file doesn't necessary follow the protocol

@@ -142,7 +143,7 @@ } else {

continue } if i < nUserTxs { - var from, to common.Account + var from, to *common.Account var err error if i%2 == 0 { from, err = randomAccount(i, true, userAddr, accounts)

@@ -216,7 +217,7 @@ EthBlockNum: blocks[i%len(blocks)].EthBlockNum,

Type: randomTxType(i), } if i < nUserTxs { - var from, to common.Account + var from, to *common.Account var err error if i%2 == 0 { from, err = randomAccount(i, true, userAddr, accounts)

@@ -262,10 +263,10 @@ func GenCoordinators(nCoords int, blocks []common.Block) []common.Coordinator {

coords := []common.Coordinator{} for i := 0; i < nCoords; i++ { coords = append(coords, common.Coordinator{ - EthBlockNum: blocks[i%len(blocks)].EthBlockNum, - Forger: ethCommon.BigToAddress(big.NewInt(int64(i))), - Withdraw: ethCommon.BigToAddress(big.NewInt(int64(i))), - URL: "https://foo.bar", + EthBlockNum: blocks[i%len(blocks)].EthBlockNum, + Forger: ethCommon.BigToAddress(big.NewInt(int64(i))), + WithdrawAddr: ethCommon.BigToAddress(big.NewInt(int64(i))), + URL: "https://foo.bar", }) } return coords

@@ -285,21 +286,51 @@ }

return bids } -func randomAccount(seed int, userAccount bool, userAddr *ethCommon.Address, accs []common.Account) (common.Account, error) { +// GenExitTree generates an exitTree (as an array of Exits) +//nolint:gomnd +func GenExitTree(n int) []common.ExitInfo { + exitTree := make([]common.ExitInfo, n) + for i := 0; i < n; i++ { + exitTree[i] = common.ExitInfo{ + BatchNum: common.BatchNum(i + 1), + InstantWithdrawn: nil, + DelayedWithdrawRequest: nil, + DelayedWithdrawn: nil, + AccountIdx: common.Idx(i * 10), + MerkleProof: &merkletree.CircomVerifierProof{ + Root: &merkletree.Hash{byte(i), byte(i + 1)}, + Siblings: []*big.Int{ + big.NewInt(int64(i) * 10), + big.NewInt(int64(i)*100 + 1), + big.NewInt(int64(i)*1000 + 2)}, + OldKey: &merkletree.Hash{byte(i * 1), byte(i*1 + 1)}, + OldValue: &merkletree.Hash{byte(i * 2), byte(i*2 + 1)}, + IsOld0: i%2 == 0, + Key: &merkletree.Hash{byte(i * 3), byte(i*3 + 1)}, + Value: &merkletree.Hash{byte(i * 4), byte(i*4 + 1)}, + Fnc: i % 2, + }, + Balance: big.NewInt(int64(i) * 1000), + } + } + return exitTree +} + +func randomAccount(seed int, userAccount bool, userAddr *ethCommon.Address, accs []common.Account) (*common.Account, error) { i := seed % len(accs) firstI := i for { acc := accs[i] if userAccount && *userAddr == acc.EthAddr { - return acc, nil + return &acc, nil } if !userAccount && (userAddr == nil || *userAddr != acc.EthAddr) { - return acc, nil + return &acc, nil } i++ i = i % len(accs) if i == firstI { - return acc, errors.New("Didnt found any account matchinng the criteria") + return &acc, errors.New("Didnt found any account matchinng the criteria") } } }
M test/l2db.go → test/l2db.go

@@ -13,10 +13,10 @@ )

// CleanL2DB deletes 'tx_pool' and 'account_creation_auth' from the given DB func CleanL2DB(db *sqlx.DB) { - if _, err := db.Exec("DELETE FROM tx_pool"); err != nil { + if _, err := db.Exec("DELETE FROM tx_pool;"); err != nil { panic(err) } - if _, err := db.Exec("DELETE FROM account_creation_auth"); err != nil { + if _, err := db.Exec("DELETE FROM account_creation_auth;"); err != nil { panic(err) } }