From 79b3de7178b095b647263c69e3faeaea889c0d03 Mon Sep 17 00:00:00 2001 From: arnaucube Date: Wed, 30 Dec 2020 14:06:59 +0100 Subject: [PATCH] Update TxSelector to return CoordIdxs used & other - StateDB - Update GetIdxByEthAddrBJJ to return ErrToIdxNotFound when idx not found, so can be checked at upper levels - TxSelector - rm CoordIdxsDB that is no longer needed (also related methods) - add `getCoordIdx` method to get the Coordinator Idx for a given TokenID - Update coordinator account creation related to new TokenIDs from L2Txs - Reorganize GetL1L2TxSelection - return CoordIdxs used in the selection - Update go-merkletree version which avoids marshaling Siblings to json with 'null' value in case of empty array --- coordinator/coordinator_test.go | 6 +- db/kvdb/kvdb.go | 7 +- db/statedb/statedb.go | 7 +- db/statedb/utils.go | 23 +++- db/statedb/utils_test.go | 4 +- go.mod | 2 +- go.sum | 4 +- txprocessor/txprocessor.go | 2 - txselector/txselector.go | 225 ++++++++++++++------------------ txselector/txselector_test.go | 20 --- 10 files changed, 133 insertions(+), 167 deletions(-) diff --git a/coordinator/coordinator_test.go b/coordinator/coordinator_test.go index af7d448..274fc96 100644 --- a/coordinator/coordinator_test.go +++ b/coordinator/coordinator_test.go @@ -29,6 +29,7 @@ import ( "github.com/hermeznetwork/hermez-node/txprocessor" "github.com/hermeznetwork/hermez-node/txselector" "github.com/hermeznetwork/tracerr" + "github.com/iden3/go-iden3-crypto/babyjub" "github.com/iden3/go-merkletree" "github.com/iden3/go-merkletree/db/pebble" "github.com/stretchr/testify/assert" @@ -115,9 +116,12 @@ func newTestModules(t *testing.T) modules { require.NoError(t, err) deleteme = append(deleteme, txSelDBPath) + var bjj babyjub.PublicKeyComp + err = bjj.UnmarshalText([]byte("c433f7a696b7aa3a5224efb3993baf0ccd9e92eecee0c29a3f6c8208a9e81d9e")) + require.NoError(t, err) coordAccount := &txselector.CoordAccount{ // TODO TMP Addr: ethCommon.HexToAddress("0xc58d29fA6e86E4FAe04DDcEd660d45BCf3Cb2370"), - BJJ: common.EmptyBJJComp, + BJJ: bjj, AccountCreationAuth: nil, } txSelector, err := txselector.NewTxSelector(coordAccount, txSelDBPath, syncStateDB, l2DB) diff --git a/db/kvdb/kvdb.go b/db/kvdb/kvdb.go index f1569e9..941dd0d 100644 --- a/db/kvdb/kvdb.go +++ b/db/kvdb/kvdb.go @@ -123,7 +123,7 @@ func (kvdb *KVDB) reset(batchNum common.BatchNum, closeCurrent bool) error { } kvdb.db = sto kvdb.CurrentIdx = 255 - kvdb.CurrentBatch = batchNum + kvdb.CurrentBatch = 0 return nil } @@ -210,6 +210,11 @@ func (kvdb *KVDB) ResetFromSynchronizer(batchNum common.BatchNum, synchronizerKV if err != nil { return tracerr.Wrap(err) } + // get currentIdx + kvdb.CurrentIdx, err = kvdb.GetCurrentIdx() + if err != nil { + return tracerr.Wrap(err) + } return nil } diff --git a/db/statedb/statedb.go b/db/statedb/statedb.go index 457d169..bbbf0d0 100644 --- a/db/statedb/statedb.go +++ b/db/statedb/statedb.go @@ -22,9 +22,9 @@ var ( // Account already exists ErrAccountAlreadyExists = errors.New("Can not CreateAccount because Account already exists") - // ErrToIdxNotFound is used when trying to get the ToIdx from ToEthAddr - // or ToEthAddr&ToBJJ - ErrToIdxNotFound = errors.New("ToIdx can not be found") + // ErrIdxNotFound is used when trying to get the Idx from EthAddr or + // EthAddr&ToBJJ + ErrIdxNotFound = errors.New("Idx can not be found") // ErrGetIdxNoCase is used when trying to get the Idx from EthAddr & // BJJ with not compatible combination ErrGetIdxNoCase = errors.New("Can not get Idx due unexpected combination of ethereum Address & BabyJubJub PublicKey") @@ -148,6 +148,7 @@ func (s *StateDB) Reset(batchNum common.BatchNum) error { } s.MT = mt } + log.Debugw("Making StateDB Reset", "batch", batchNum) return nil } diff --git a/db/statedb/utils.go b/db/statedb/utils.go index c529a09..cba61f8 100644 --- a/db/statedb/utils.go +++ b/db/statedb/utils.go @@ -9,6 +9,7 @@ import ( "github.com/hermeznetwork/hermez-node/log" "github.com/hermeznetwork/tracerr" "github.com/iden3/go-iden3-crypto/babyjub" + "github.com/iden3/go-merkletree/db" ) func concatEthAddrTokenID(addr ethCommon.Address, tokenID common.TokenID) []byte { @@ -84,7 +85,7 @@ func (s *StateDB) GetIdxByEthAddr(addr ethCommon.Address, tokenID common.TokenID b, err := s.db.DB().Get(append(PrefixKeyAddr, k...)) if err != nil { return common.Idx(0), tracerr.Wrap(fmt.Errorf("GetIdxByEthAddr: %s: ToEthAddr: %s, TokenID: %d", - ErrToIdxNotFound, addr.Hex(), tokenID)) + ErrIdxNotFound, addr.Hex(), tokenID)) } idx, err := common.IdxFromBytes(b) if err != nil { @@ -99,26 +100,34 @@ func (s *StateDB) GetIdxByEthAddr(addr ethCommon.Address, tokenID common.TokenID // address, it's ignored in the query. If `pk` is nil, it's ignored in the // query. Will return common.Idx(0) and error in case that Idx is not found in // the StateDB. -func (s *StateDB) GetIdxByEthAddrBJJ(addr ethCommon.Address, pk babyjub.PublicKeyComp, tokenID common.TokenID) (common.Idx, error) { +func (s *StateDB) GetIdxByEthAddrBJJ(addr ethCommon.Address, pk babyjub.PublicKeyComp, + tokenID common.TokenID) (common.Idx, error) { if !bytes.Equal(addr.Bytes(), common.EmptyAddr.Bytes()) && pk == common.EmptyBJJComp { // ToEthAddr // case ToEthAddr!=0 && ToBJJ=0 return s.GetIdxByEthAddr(addr, tokenID) - } else if !bytes.Equal(addr.Bytes(), common.EmptyAddr.Bytes()) && pk != common.EmptyBJJComp { + } else if !bytes.Equal(addr.Bytes(), common.EmptyAddr.Bytes()) && + pk != common.EmptyBJJComp { // case ToEthAddr!=0 && ToBJJ!=0 k := concatEthAddrBJJTokenID(addr, pk, tokenID) b, err := s.db.DB().Get(append(PrefixKeyAddrBJJ, k...)) - if err != nil { - return common.Idx(0), tracerr.Wrap(fmt.Errorf("GetIdxByEthAddrBJJ: %s: ToEthAddr: %s, ToBJJ: %s, TokenID: %d", ErrToIdxNotFound, addr.Hex(), pk, tokenID)) + if tracerr.Unwrap(err) == db.ErrNotFound { + // return the error (ErrNotFound), so can be traced at upper layers + return common.Idx(0), tracerr.Wrap(ErrIdxNotFound) + } else if err != nil { + return common.Idx(0), + tracerr.Wrap(fmt.Errorf("GetIdxByEthAddrBJJ: %s: ToEthAddr: %s, ToBJJ: %s, TokenID: %d", ErrIdxNotFound, addr.Hex(), pk, tokenID)) } idx, err := common.IdxFromBytes(b) if err != nil { - return common.Idx(0), tracerr.Wrap(fmt.Errorf("GetIdxByEthAddrBJJ: %s: ToEthAddr: %s, ToBJJ: %s, TokenID: %d", err, addr.Hex(), pk, tokenID)) + return common.Idx(0), + tracerr.Wrap(fmt.Errorf("GetIdxByEthAddrBJJ: %s: ToEthAddr: %s, ToBJJ: %s, TokenID: %d", err, addr.Hex(), pk, tokenID)) } return idx, nil } // rest of cases (included case ToEthAddr==0) are not possible - return common.Idx(0), tracerr.Wrap(fmt.Errorf("GetIdxByEthAddrBJJ: Not found, %s: ToEthAddr: %s, ToBJJ: %s, TokenID: %d", ErrGetIdxNoCase, addr.Hex(), pk, tokenID)) + return common.Idx(0), + tracerr.Wrap(fmt.Errorf("GetIdxByEthAddrBJJ: Not found, %s: ToEthAddr: %s, ToBJJ: %s, TokenID: %d", ErrGetIdxNoCase, addr.Hex(), pk, tokenID)) } // GetTokenIDsFromIdxs returns a map containing the common.TokenID with its diff --git a/db/statedb/utils_test.go b/db/statedb/utils_test.go index 41735bc..9c33844 100644 --- a/db/statedb/utils_test.go +++ b/db/statedb/utils_test.go @@ -1,7 +1,6 @@ package statedb import ( - "fmt" "io/ioutil" "os" "testing" @@ -83,8 +82,7 @@ func TestGetIdx(t *testing.T) { // expect error when trying to get Idx by addr2 & pk2 idxR, err = sdb.GetIdxByEthAddrBJJ(addr2, pk2.Compress(), tokenID0) assert.NotNil(t, err) - expectedErr := fmt.Errorf("GetIdxByEthAddrBJJ: %s: ToEthAddr: %s, ToBJJ: %s, TokenID: %d", ErrToIdxNotFound, addr2.Hex(), pk2, tokenID0) - assert.Equal(t, expectedErr, tracerr.Unwrap(err)) + assert.Equal(t, ErrIdxNotFound, tracerr.Unwrap(err)) assert.Equal(t, common.Idx(0), idxR) // expect error when trying to get Idx by addr with not used TokenID _, err = sdb.GetIdxByEthAddr(addr, tokenID1) diff --git a/go.mod b/go.mod index cf77a1a..1706c7f 100644 --- a/go.mod +++ b/go.mod @@ -13,7 +13,7 @@ require ( github.com/gobuffalo/packr/v2 v2.8.1 github.com/hermeznetwork/tracerr v0.3.1-0.20201126162137-de9930d0cf29 github.com/iden3/go-iden3-crypto v0.0.6-0.20201221160344-58e589b6eb4c - github.com/iden3/go-merkletree v0.0.0-20201230093451-4280a9914f51 + github.com/iden3/go-merkletree v0.0.0-20201231091158-d73b96c55fbb github.com/jinzhu/copier v0.0.0-20190924061706-b57f9002281a github.com/jmoiron/sqlx v1.2.1-0.20200615141059-0794cb1f47ee github.com/joho/godotenv v1.3.0 diff --git a/go.sum b/go.sum index caa0339..ba416d5 100644 --- a/go.sum +++ b/go.sum @@ -309,8 +309,8 @@ github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3 github.com/iden3/go-iden3-crypto v0.0.6-0.20201218111145-a2015adb2f1b/go.mod h1:oBgthFLboAWi9feaBUFy7OxEcyn9vA1khHSL/WwWFyg= github.com/iden3/go-iden3-crypto v0.0.6-0.20201221160344-58e589b6eb4c h1:D2u8FFYey6iFXLsqqJZ8R7ch8gZum+/b98whvoSDbyg= github.com/iden3/go-iden3-crypto v0.0.6-0.20201221160344-58e589b6eb4c/go.mod h1:oBgthFLboAWi9feaBUFy7OxEcyn9vA1khHSL/WwWFyg= -github.com/iden3/go-merkletree v0.0.0-20201230093451-4280a9914f51 h1:EqkLnC+JlOdX3hQnjq0u2JKcMMmmaQcpmG1udG6BTXw= -github.com/iden3/go-merkletree v0.0.0-20201230093451-4280a9914f51/go.mod h1:MCXbnyoFRwt+7aYHtzVSB3sZZcHLjDf7VZZ2Zqrhqrc= +github.com/iden3/go-merkletree v0.0.0-20201231091158-d73b96c55fbb h1:nwjQVe4nYNC6lwF4gAtSdmQ3vMkm0NpJzJVhoWpfSBc= +github.com/iden3/go-merkletree v0.0.0-20201231091158-d73b96c55fbb/go.mod h1:MCXbnyoFRwt+7aYHtzVSB3sZZcHLjDf7VZZ2Zqrhqrc= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/influxdata/influxdb v1.2.3-0.20180221223340-01288bdb0883/go.mod h1:qZna6X/4elxqT3yI9iZYdZrWWdeFOOprn86kgg4+IzY= github.com/influxdata/influxdb1-client v0.0.0-20190809212627-fc22c7df067e/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= diff --git a/txprocessor/txprocessor.go b/txprocessor/txprocessor.go index ba8e922..c18a771 100644 --- a/txprocessor/txprocessor.go +++ b/txprocessor/txprocessor.go @@ -99,8 +99,6 @@ func (tp *TxProcessor) ProcessTxs(coordIdxs []common.Idx, l1usertxs, l1coordinat return nil, tracerr.Wrap(fmt.Errorf("CoordIdxs (%d) length must be smaller than MaxFeeTx (%d)", len(coordIdxs), tp.config.MaxFeeTx)) } - tp.AccumulatedFees = make(map[common.Idx]*big.Int) - nTx := len(l1usertxs) + len(l1coordinatortxs) + len(l2txs) if nTx > int(tp.config.MaxTx) { diff --git a/txselector/txselector.go b/txselector/txselector.go index 4f203b7..80d59c3 100644 --- a/txselector/txselector.go +++ b/txselector/txselector.go @@ -17,7 +17,6 @@ import ( "github.com/hermeznetwork/tracerr" "github.com/iden3/go-iden3-crypto/babyjub" "github.com/iden3/go-merkletree/db" - "github.com/iden3/go-merkletree/db/pebble" ) const ( @@ -67,7 +66,6 @@ type TxSelector struct { localAccountsDB *statedb.LocalStateDB coordAccount *CoordAccount - coordIdxsDB *pebble.Storage } // NewTxSelector returns a *TxSelector @@ -79,16 +77,10 @@ func NewTxSelector(coordAccount *CoordAccount, dbpath string, return nil, tracerr.Wrap(err) } - coordIdxsDB, err := pebble.NewPebbleStorage(dbpath+PathCoordIdxsDB, false) - if err != nil { - return nil, tracerr.Wrap(err) - } - return &TxSelector{ l2db: l2, localAccountsDB: localAccountsDB, coordAccount: coordAccount, - coordIdxsDB: coordIdxsDB, }, nil } @@ -107,65 +99,35 @@ func (txsel *TxSelector) Reset(batchNum common.BatchNum) error { return nil } -// AddCoordIdxs stores the given TokenID with the correspondent Idx to the -// CoordIdxsDB -func (txsel *TxSelector) AddCoordIdxs(idxs map[common.TokenID]common.Idx) error { - tx, err := txsel.coordIdxsDB.NewTx() - if err != nil { - return tracerr.Wrap(err) - } - for tokenID, idx := range idxs { - idxBytes, err := idx.Bytes() - if err != nil { - return tracerr.Wrap(err) - } - err = tx.Put(tokenID.Bytes(), idxBytes[:]) - if err != nil { - return tracerr.Wrap(err) - } - } - if err := tx.Commit(); err != nil { - return tracerr.Wrap(err) - } - return nil -} - -// GetCoordIdxs returns a map with the stored TokenID with the correspondent -// Coordinator Idx -func (txsel *TxSelector) GetCoordIdxs() (map[common.TokenID]common.Idx, error) { - r := make(map[common.TokenID]common.Idx) - err := txsel.coordIdxsDB.Iterate(func(tokenIDBytes []byte, idxBytes []byte) (bool, error) { - idx, err := common.IdxFromBytes(idxBytes) - if err != nil { - return false, tracerr.Wrap(err) - } - tokenID, err := common.TokenIDFromBytes(tokenIDBytes) - if err != nil { - return false, tracerr.Wrap(err) - } - r[tokenID] = idx - return true, nil - }) - - return r, tracerr.Wrap(err) +func (txsel *TxSelector) getCoordIdx(tokenID common.TokenID) (common.Idx, error) { + return txsel.localAccountsDB.GetIdxByEthAddrBJJ(txsel.coordAccount.Addr, txsel.coordAccount.BJJ, tokenID) } +// coordAccountForTokenID creates a new L1CoordinatorTx to create a new +// Coordinator account for the given TokenID in the case that the account does +// not exist yet in the db, and does not exist a L1CoordinatorTx to creat that +// account in the given array of L1CoordinatorTxs. If a new Coordinator account +// needs to be created, a new L1CoordinatorTx will be returned from this +// function. //nolint:unused -func (txsel *TxSelector) coordAccountForTokenID(l1CoordinatorTxs []common.L1Tx, tokenID common.TokenID, positionL1 int) (*common.L1Tx, int, error) { +func (txsel *TxSelector) coordAccountForTokenID(l1CoordinatorTxs []common.L1Tx, + tokenID common.TokenID, positionL1 int) (*common.L1Tx, int, error) { // check if CoordinatorAccount for TokenID is already pending to create - if checkAlreadyPendingToCreate(l1CoordinatorTxs, tokenID, txsel.coordAccount.Addr, txsel.coordAccount.BJJ) { + if checkAlreadyPendingToCreate(l1CoordinatorTxs, tokenID, + txsel.coordAccount.Addr, txsel.coordAccount.BJJ) { return nil, positionL1, nil } - - _, err := txsel.coordIdxsDB.Get(tokenID.Bytes()) - if tracerr.Unwrap(err) == db.ErrNotFound { - // create L1CoordinatorTx to create new CoordAccount for TokenID + _, err := txsel.localAccountsDB.GetIdxByEthAddrBJJ(txsel.coordAccount.Addr, txsel.coordAccount.BJJ, tokenID) + if tracerr.Unwrap(err) == statedb.ErrIdxNotFound { + // create L1CoordinatorTx to create new CoordAccount for + // TokenID l1CoordinatorTx := common.L1Tx{ Position: positionL1, UserOrigin: false, FromEthAddr: txsel.coordAccount.Addr, FromBJJ: txsel.coordAccount.BJJ, TokenID: tokenID, + Amount: big.NewInt(0), DepositAmount: big.NewInt(0), Type: common.TxTypeCreateAccountDeposit, } @@ -191,8 +153,8 @@ func (txsel *TxSelector) coordAccountForTokenID(l1CoordinatorTxs []common.L1Tx, // included in the next batch. func (txsel *TxSelector) GetL2TxSelection(selectionConfig *SelectionConfig, batchNum common.BatchNum) ([]common.Idx, [][]byte, []common.L1Tx, []common.PoolL2Tx, error) { - coordIdxs, accCreationAuths, _, l1CoordinatorTxs, l2Txs, err := txsel.GetL1L2TxSelection(selectionConfig, batchNum, - []common.L1Tx{}) + coordIdxs, accCreationAuths, _, l1CoordinatorTxs, l2Txs, err := + txsel.GetL1L2TxSelection(selectionConfig, batchNum, []common.L1Tx{}) return coordIdxs, accCreationAuths, l1CoordinatorTxs, l2Txs, tracerr.Wrap(err) } @@ -205,30 +167,15 @@ func (txsel *TxSelector) GetL2TxSelection(selectionConfig *SelectionConfig, // creation exists. The L1UserTxs, L1CoordinatorTxs, PoolL2Txs that will be // included in the next batch. func (txsel *TxSelector) GetL1L2TxSelection(selectionConfig *SelectionConfig, - batchNum common.BatchNum, l1Txs []common.L1Tx) ([]common.Idx, [][]byte, []common.L1Tx, []common.L1Tx, - []common.PoolL2Tx, error) { + batchNum common.BatchNum, l1Txs []common.L1Tx) ([]common.Idx, [][]byte, []common.L1Tx, + []common.L1Tx, []common.PoolL2Tx, error) { // TODO WIP this method uses a 'cherry-pick' of internal calls of the // StateDB, a refactor of the StateDB to reorganize it internally is // planned once the main functionallities are covered, with that // refactor the TxSelector will be updated also - // apply l1-user-tx to localAccountDB - // create new leaves - // update balances - // update nonces - - // get existing CoordIdxs - coordIdxsMap, err := txsel.GetCoordIdxs() - if err != nil { - return nil, nil, nil, nil, nil, tracerr.Wrap(err) - } - var coordIdxs []common.Idx - for tokenID := range coordIdxsMap { - coordIdxs = append(coordIdxs, coordIdxsMap[tokenID]) - } - // get pending l2-tx from tx-pool - l2TxsRaw, err := txsel.l2db.GetPendingTxs() // (batchID) + l2TxsRaw, err := txsel.l2db.GetPendingTxs() if err != nil { return nil, nil, nil, nil, nil, tracerr.Wrap(err) } @@ -236,10 +183,6 @@ func (txsel *TxSelector) GetL1L2TxSelection(selectionConfig *SelectionConfig, txselStateDB := txsel.localAccountsDB.StateDB tp := txprocessor.NewTxProcessor(txselStateDB, selectionConfig.TxProcessorConfig) - var validTxs txs - var l1CoordinatorTxs []common.L1Tx - positionL1 := len(l1Txs) - // Process L1UserTxs for i := 0; i < len(l1Txs); i++ { // assumption: l1usertx are sorted by L1Tx.Position @@ -249,12 +192,51 @@ func (txsel *TxSelector) GetL1L2TxSelection(selectionConfig *SelectionConfig, } } - // get last idx from LocalStateDB - // lastIdx := txsel.localStateDB.idx - // update lastIdx with the L1UserTxs (of account creation) - + var l1CoordinatorTxs []common.L1Tx + positionL1 := len(l1Txs) var accAuths [][]byte - for i := 0; i < len(l2TxsRaw); i++ { + + // sort l2TxsRaw (cropping at MaxTx at this point) + l2Txs := txsel.getL2Profitable(l2TxsRaw, selectionConfig.TxProcessorConfig.MaxTx) + + // TODO for L1CoordinatorTxs check that always len(l1UserTxs)+len(l1CoordinatorTxs)=256, tx.ToIdx should exist to localAccountsDB, // if so, tx is used. If tx.ToIdx==0, for an L2Tx will be the // case of TxToEthAddr or TxToBJJ, check if @@ -263,11 +245,11 @@ func (txsel *TxSelector) GetL1L2TxSelection(selectionConfig *SelectionConfig, // AccountCreationAuthDB, if so, tx is used and L1CoordinatorTx // of CreateAccountAndDeposit is created. If tx.ToIdx==1, is a // Exit type and is used. - if l2TxsRaw[i].ToIdx == 0 { // ToEthAddr/ToBJJ case + if l2Txs[i].ToIdx == 0 { // ToEthAddr/ToBJJ case var accAuth *common.AccountCreationAuth validTxs, l1CoordinatorTxs, accAuth, positionL1, err = txsel.processTxToEthAddrBJJ(validTxs, l1CoordinatorTxs, - positionL1, l2TxsRaw[i]) + positionL1, l2Txs[i]) if err != nil { log.Debug(err) continue @@ -275,33 +257,22 @@ func (txsel *TxSelector) GetL1L2TxSelection(selectionConfig *SelectionConfig, if accAuth != nil { accAuths = append(accAuths, accAuth.Signature) } - } else if l2TxsRaw[i].ToIdx >= common.IdxUserThreshold { - _, err = txsel.localAccountsDB.GetAccount(l2TxsRaw[i].ToIdx) + } else if l2Txs[i].ToIdx >= common.IdxUserThreshold { + _, err = txsel.localAccountsDB.GetAccount(l2Txs[i].ToIdx) if err != nil { // tx not valid log.Debugw("invalid L2Tx: ToIdx not found in StateDB", - "ToIdx", l2TxsRaw[i].ToIdx) + "ToIdx", l2Txs[i].ToIdx) continue } - // TODO if EthAddr!=0 or BJJ!=0, check that ToIdxAccount.EthAddr or BJJ // Account found in the DB, include the l2Tx in the selection - validTxs = append(validTxs, l2TxsRaw[i]) - } else if l2TxsRaw[i].ToIdx == common.Idx(1) { + validTxs = append(validTxs, l2Txs[i]) + } else if l2Txs[i].ToIdx == common.Idx(1) { // valid txs (of Exit type) - validTxs = append(validTxs, l2TxsRaw[i]) + validTxs = append(validTxs, l2Txs[i]) } - // TODO if needed add L1CoordinatorTx to create a Coordinator - // account for the new TokenID - // var newL1CoordTx *common.L1Tx - // newL1CoordTx, positionL1, err = txsel.coordAccountForTokenID(l1CoordinatorTxs, l2TxsRaw[i].TokenID, positionL1) - // if err != nil { - // return nil, nil, nil, nil, nil, tracerr.Wrap(err) - // } - // if newL1CoordTx != nil { - // l1CoordinatorTxs = append(l1CoordinatorTxs, *newL1CoordTx) - // } } // Process L1CoordinatorTxs @@ -311,41 +282,39 @@ func (txsel *TxSelector) GetL1L2TxSelection(selectionConfig *SelectionConfig, return nil, nil, nil, nil, nil, tracerr.Wrap(err) } } + + // get CoordIdxsMap for the TokenIDs + coordIdxsMap := make(map[common.TokenID]common.Idx) + // TODO TMP (related to L#260 + // for i := 0; i < len(l2Txs); i++ { + // coordIdx, err := txsel.getCoordIdx(l2Txs[i].TokenID) + // if err != nil { + // // if err is db.ErrNotFound, should not happen, as all + // // the l2Txs.TokenID should have a CoordinatorIdx + // // created in the DB at this point + // return nil, nil, nil, nil, nil, tracerr.Wrap(err) + // } + // coordIdxsMap[l2Txs[i].TokenID] = coordIdx + // } + + var coordIdxs []common.Idx tp.AccumulatedFees = make(map[common.Idx]*big.Int) - for _, idx := range coordIdxs { + for _, idx := range coordIdxsMap { tp.AccumulatedFees[idx] = big.NewInt(0) - } - - // once L1UserTxs & L1CoordinatorTxs are processed, get TokenIDs of - // coordIdxs. In this way, if a coordIdx uses an Idx that is being - // created in the current batch, at this point the Idx will be created - coordIdxsMap, err = txsel.localAccountsDB.GetTokenIDsFromIdxs(coordIdxs) - if err != nil { - return nil, nil, nil, nil, nil, tracerr.Wrap(err) + coordIdxs = append(coordIdxs, idx) } // get most profitable L2-tx maxL2Txs := selectionConfig.TxProcessorConfig.MaxTx - uint32(len(l1CoordinatorTxs)) // - len(l1UserTxs) // TODO if there are L1UserTxs take them in to account - l2Txs := txsel.getL2Profitable(validTxs, maxL2Txs) - - // Process L2Txs - for i := 0; i < len(l2Txs); i++ { - _, _, _, err = tp.ProcessL2Tx(coordIdxsMap, nil, nil, &l2Txs[i]) + selectedL2Txs := txsel.getL2Profitable(l2Txs, maxL2Txs) // TODO this will only need to crop the lasts, as are already sorted + for i := 0; i < len(selectedL2Txs); i++ { + _, _, _, err = tp.ProcessL2Tx(coordIdxsMap, nil, nil, &selectedL2Txs[i]) if err != nil { return nil, nil, nil, nil, nil, tracerr.Wrap(err) } } - err = txsel.AddCoordIdxs(coordIdxsMap) - if err != nil { - return nil, nil, nil, nil, nil, tracerr.Wrap(err) - } - - err = txsel.localAccountsDB.MakeCheckpoint() - if err != nil { - return nil, nil, nil, nil, nil, tracerr.Wrap(err) - } - return nil, accAuths, l1Txs, l1CoordinatorTxs, l2Txs, nil + return coordIdxs, accAuths, l1Txs, l1CoordinatorTxs, selectedL2Txs, nil } // processTxsToEthAddrBJJ process the common.PoolL2Tx in the case where @@ -424,6 +393,7 @@ func (txsel *TxSelector) processTxToEthAddrBJJ(validTxs txs, l1CoordinatorTxs [] FromEthAddr: accAuth.EthAddr, FromBJJ: accAuth.BJJ, TokenID: l2Tx.TokenID, + Amount: big.NewInt(0), DepositAmount: big.NewInt(0), Type: common.TxTypeCreateAccountDeposit, } @@ -450,6 +420,7 @@ func (txsel *TxSelector) processTxToEthAddrBJJ(validTxs txs, l1CoordinatorTxs [] FromEthAddr: l2Tx.ToEthAddr, FromBJJ: l2Tx.ToBJJ, TokenID: l2Tx.TokenID, + Amount: big.NewInt(0), DepositAmount: big.NewInt(0), Type: common.TxTypeCreateAccountDeposit, } diff --git a/txselector/txselector_test.go b/txselector/txselector_test.go index d12b3c5..3b3a7e8 100644 --- a/txselector/txselector_test.go +++ b/txselector/txselector_test.go @@ -64,24 +64,6 @@ func addTokens(t *testing.T, tokens []common.Token, db *sqlx.DB) { assert.NoError(t, hdb.AddTokens(tokens)) } -func TestCoordIdxsDB(t *testing.T) { - chainID := uint16(0) - txsel := initTest(t, chainID, til.SetPool0) - test.WipeDB(txsel.l2db.DB()) - - coordIdxs := make(map[common.TokenID]common.Idx) - coordIdxs[common.TokenID(0)] = common.Idx(256) - coordIdxs[common.TokenID(1)] = common.Idx(257) - coordIdxs[common.TokenID(2)] = common.Idx(258) - - err := txsel.AddCoordIdxs(coordIdxs) - assert.NoError(t, err) - - r, err := txsel.GetCoordIdxs() - assert.NoError(t, err) - assert.Equal(t, coordIdxs, r) -} - func TestGetL2TxSelection(t *testing.T) { chainID := uint16(0) txsel := initTest(t, chainID, til.SetPool0) @@ -99,8 +81,6 @@ func TestGetL2TxSelection(t *testing.T) { coordIdxs[common.TokenID(1)] = common.Idx(257) coordIdxs[common.TokenID(2)] = common.Idx(258) coordIdxs[common.TokenID(3)] = common.Idx(259) - err = txsel.AddCoordIdxs(coordIdxs) - assert.NoError(t, err) // add tokens to HistoryDB to avoid breaking FK constrains var tokens []common.Token