From efb23950db3ffa2b42495f4fa1395e629577587d Mon Sep 17 00:00:00 2001 From: Pantani Date: Mon, 8 Mar 2021 14:41:19 -0300 Subject: [PATCH] Synchronize the AccountCreationAuths from L1CoordinatorTxs --- coordinator/coordinator_test.go | 2 +- db/l2db/l2db.go | 10 +++++++++ db/l2db/l2db_test.go | 37 +++++++++++++++++++++++++++++++ node/node.go | 24 +++++++++++--------- synchronizer/synchronizer.go | 31 ++++++++++++++++++++++++-- synchronizer/synchronizer_test.go | 18 +++++++++------ test/ethclient.go | 6 ++++- 7 files changed, 106 insertions(+), 22 deletions(-) diff --git a/coordinator/coordinator_test.go b/coordinator/coordinator_test.go index d51dff5..acdb780 100644 --- a/coordinator/coordinator_test.go +++ b/coordinator/coordinator_test.go @@ -206,7 +206,7 @@ func newTestCoordinator(t *testing.T, forgerAddr ethCommon.Address, ethClient *t func newTestSynchronizer(t *testing.T, ethClient *test.Client, ethClientSetup *test.ClientSetup, modules modules) *synchronizer.Synchronizer { - sync, err := synchronizer.NewSynchronizer(ethClient, modules.historyDB, modules.stateDB, + sync, err := synchronizer.NewSynchronizer(ethClient, modules.historyDB, modules.l2DB, modules.stateDB, synchronizer.Config{ StatsRefreshPeriod: 0 * time.Second, }) diff --git a/db/l2db/l2db.go b/db/l2db/l2db.go index aeeaffa..bbc64d7 100644 --- a/db/l2db/l2db.go +++ b/db/l2db/l2db.go @@ -74,6 +74,16 @@ func (l2db *L2DB) AddAccountCreationAuth(auth *common.AccountCreationAuth) error return tracerr.Wrap(err) } +// AddManyAccountCreationAuth inserts a batch of accounts creation authorization +// if not exist into the DB +func (l2db *L2DB) AddManyAccountCreationAuth(auths []common.AccountCreationAuth) error { + _, err := sqlx.NamedExec(l2db.dbWrite, + `INSERT INTO account_creation_auth (eth_addr, bjj, signature) + VALUES (:ethaddr, :bjj, :signature) + ON CONFLICT (eth_addr) DO NOTHING`, auths) + return tracerr.Wrap(err) +} + // GetAccountCreationAuth returns an account creation authorization from the DB func (l2db *L2DB) GetAccountCreationAuth(addr ethCommon.Address) (*common.AccountCreationAuth, error) { auth := new(common.AccountCreationAuth) diff --git a/db/l2db/l2db_test.go b/db/l2db/l2db_test.go index 45db439..6bf02e9 100644 --- a/db/l2db/l2db_test.go +++ b/db/l2db/l2db_test.go @@ -725,6 +725,43 @@ func TestAuth(t *testing.T) { } } +func TestManyAuth(t *testing.T) { + test.WipeDB(l2DB.DB()) + const nAuths = 5 + chainID := uint16(0) + hermezContractAddr := ethCommon.HexToAddress("0xc344E203a046Da13b0B4467EB7B3629D0C99F6E6") + // Generate authorizations + genAuths := test.GenAuths(nAuths, chainID, hermezContractAddr) + auths := make([]common.AccountCreationAuth, len(genAuths)) + // Convert to a non-pointer slice + for i := 0; i < len(genAuths); i++ { + auths[i] = *genAuths[i] + } + + // Add a duplicate one to check the not exist condition + err := l2DB.AddAccountCreationAuth(genAuths[0]) + require.NoError(t, err) + + // Add to the DB + err = l2DB.AddManyAccountCreationAuth(auths) + require.NoError(t, err) + + // Assert the result + for i := 0; i < len(auths); i++ { + // Fetch from DB + auth, err := l2DB.GetAccountCreationAuth(auths[i].EthAddr) + require.NoError(t, err) + // Check fetched vs generated + assert.Equal(t, auths[i].EthAddr, auth.EthAddr) + assert.Equal(t, auths[i].BJJ, auth.BJJ) + assert.Equal(t, auths[i].Signature, auth.Signature) + assert.Equal(t, auths[i].Timestamp.Unix(), auths[i].Timestamp.Unix()) + nameZone, offset := auths[i].Timestamp.Zone() + assert.Equal(t, "UTC", nameZone) + assert.Equal(t, 0, offset) + } +} + func TestAddGet(t *testing.T) { err := prepareHistoryDB(historyDB) if err != nil { diff --git a/node/node.go b/node/node.go index bfd7036..a004a2c 100644 --- a/node/node.go +++ b/node/node.go @@ -220,7 +220,19 @@ func NewNode(mode Mode, cfg *config.Node) (*Node, error) { return nil, tracerr.Wrap(err) } - sync, err := synchronizer.NewSynchronizer(client, historyDB, stateDB, synchronizer.Config{ + var l2DB *l2db.L2DB + if mode == ModeCoordinator { + l2DB = l2db.NewL2DB( + dbRead, dbWrite, + cfg.Coordinator.L2DB.SafetyPeriod, + cfg.Coordinator.L2DB.MaxTxs, + cfg.Coordinator.L2DB.MinFeeUSD, + cfg.Coordinator.L2DB.TTL.Duration, + apiConnCon, + ) + } + + sync, err := synchronizer.NewSynchronizer(client, historyDB, l2DB, stateDB, synchronizer.Config{ StatsRefreshPeriod: cfg.Synchronizer.StatsRefreshPeriod.Duration, ChainID: chainIDU16, }) @@ -236,17 +248,7 @@ func NewNode(mode Mode, cfg *config.Node) (*Node, error) { } var coord *coordinator.Coordinator - var l2DB *l2db.L2DB if mode == ModeCoordinator { - l2DB = l2db.NewL2DB( - dbRead, dbWrite, - cfg.Coordinator.L2DB.SafetyPeriod, - cfg.Coordinator.L2DB.MaxTxs, - cfg.Coordinator.L2DB.MinFeeUSD, - cfg.Coordinator.L2DB.TTL.Duration, - apiConnCon, - ) - // Unlock FeeAccount EthAddr in the keystore to generate the // account creation authorization if !keyStore.HasAddress(cfg.Coordinator.FeeAccount.Address) { diff --git a/synchronizer/synchronizer.go b/synchronizer/synchronizer.go index f41adac..8e7f2dd 100644 --- a/synchronizer/synchronizer.go +++ b/synchronizer/synchronizer.go @@ -11,6 +11,7 @@ import ( "github.com/ethereum/go-ethereum" "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/hermez-node/eth" "github.com/hermeznetwork/hermez-node/log" @@ -215,6 +216,7 @@ type Synchronizer struct { ethClient eth.ClientInterface consts SCConsts historyDB *historydb.HistoryDB + l2DB *l2db.L2DB stateDB *statedb.StateDB cfg Config initVars SCVariables @@ -226,7 +228,7 @@ type Synchronizer struct { // NewSynchronizer creates a new Synchronizer func NewSynchronizer(ethClient eth.ClientInterface, historyDB *historydb.HistoryDB, - stateDB *statedb.StateDB, cfg Config) (*Synchronizer, error) { + l2DB *l2db.L2DB, stateDB *statedb.StateDB, cfg Config) (*Synchronizer, error) { auctionConstants, err := ethClient.AuctionConstants() if err != nil { return nil, tracerr.Wrap(fmt.Errorf("NewSynchronizer ethClient.AuctionConstants(): %w", @@ -271,6 +273,7 @@ func NewSynchronizer(ethClient eth.ClientInterface, historyDB *historydb.History ethClient: ethClient, consts: consts, historyDB: historyDB, + l2DB: l2DB, stateDB: stateDB, cfg: cfg, initVars: *initVars, @@ -657,7 +660,7 @@ func (s *Synchronizer) Sync(ctx context.Context, if len(rollupData.Batches) > 0 { hasBatch = true } - if err := s.updateCurrentNextSlotIfSync(false, hasBatch); err != nil { + if err = s.updateCurrentNextSlotIfSync(false, hasBatch); err != nil { return nil, nil, tracerr.Wrap(err) } @@ -895,6 +898,9 @@ func (s *Synchronizer) rollupSync(ethBlock *common.Block) (*common.RollupData, e position = len(l1UserTxs) } + + l1TxsAuth := make([]common.AccountCreationAuth, + 0, len(forgeBatchArgs.L1CoordinatorTxsAuths)) // Get L1 Coordinator Txs for i := range forgeBatchArgs.L1CoordinatorTxs { l1CoordinatorTx := forgeBatchArgs.L1CoordinatorTxs[i] @@ -910,9 +916,30 @@ func (s *Synchronizer) rollupSync(ethBlock *common.Block) (*common.RollupData, e batchData.L1CoordinatorTxs = append(batchData.L1CoordinatorTxs, *l1Tx) position++ + + // Create a slice of account creation auth to be + // inserted later if not exists + if l1CoordinatorTx.FromEthAddr != common.RollupConstEthAddressInternalOnly { + l1CoordinatorTxAuth := forgeBatchArgs.L1CoordinatorTxsAuths[i] + l1TxsAuth = append(l1TxsAuth, common.AccountCreationAuth{ + EthAddr: l1CoordinatorTx.FromEthAddr, + BJJ: l1CoordinatorTx.FromBJJ, + Signature: l1CoordinatorTxAuth, + }) + } + // fmt.Println("DGB l1coordtx") } + // Insert the slice of account creation auth + // only if the node run as a coordinator + if s.l2DB != nil && len(l1TxsAuth) > 0 { + err = s.l2DB.AddManyAccountCreationAuth(l1TxsAuth) + if err != nil { + return nil, tracerr.Wrap(err) + } + } + // Insert all the txs forged in this batch (l1UserTxs, // L1CoordinatorTxs, PoolL2Txs) into stateDB so that they are // processed. diff --git a/synchronizer/synchronizer_test.go b/synchronizer/synchronizer_test.go index 6cd2300..5f4f831 100644 --- a/synchronizer/synchronizer_test.go +++ b/synchronizer/synchronizer_test.go @@ -15,6 +15,7 @@ import ( "github.com/hermeznetwork/hermez-node/common" dbUtils "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/eth" "github.com/hermeznetwork/hermez-node/test" @@ -303,7 +304,7 @@ func TestMain(m *testing.M) { os.Exit(exitVal) } -func newTestModules(t *testing.T) (*statedb.StateDB, *historydb.HistoryDB) { +func newTestModules(t *testing.T) (*statedb.StateDB, *historydb.HistoryDB, *l2db.L2DB) { // Int State DB dir, err := ioutil.TempDir("", "tmpdb") require.NoError(t, err) @@ -321,7 +322,10 @@ func newTestModules(t *testing.T) (*statedb.StateDB, *historydb.HistoryDB) { // Clear DB test.WipeDB(historyDB.DB()) - return stateDB, historyDB + // Init L2 DB + l2DB := l2db.NewL2DB(db, db, 10, 100, 0.0, 24*time.Hour, nil) + + return stateDB, historyDB, l2DB } func newBigInt(s string) *big.Int { @@ -337,7 +341,7 @@ func TestSyncGeneral(t *testing.T) { // Setup // - stateDB, historyDB := newTestModules(t) + stateDB, historyDB, l2DB := newTestModules(t) // Init eth client var timer timer @@ -347,7 +351,7 @@ func TestSyncGeneral(t *testing.T) { client := test.NewClient(true, &timer, ðCommon.Address{}, clientSetup) // Create Synchronizer - s, err := NewSynchronizer(client, historyDB, stateDB, Config{ + s, err := NewSynchronizer(client, historyDB, l2DB, stateDB, Config{ StatsRefreshPeriod: 0 * time.Second, }) require.NoError(t, err) @@ -727,7 +731,7 @@ func TestSyncGeneral(t *testing.T) { } func TestSyncForgerCommitment(t *testing.T) { - stateDB, historyDB := newTestModules(t) + stateDB, historyDB, l2DB := newTestModules(t) // Init eth client var timer timer @@ -740,7 +744,7 @@ func TestSyncForgerCommitment(t *testing.T) { client := test.NewClient(true, &timer, ðCommon.Address{}, clientSetup) // Create Synchronizer - s, err := NewSynchronizer(client, historyDB, stateDB, Config{ + s, err := NewSynchronizer(client, historyDB, l2DB, stateDB, Config{ StatsRefreshPeriod: 0 * time.Second, }) require.NoError(t, err) @@ -840,7 +844,7 @@ func TestSyncForgerCommitment(t *testing.T) { require.True(t, stats.Synced()) syncCommitment[syncBlock.Block.Num] = stats.Sync.Auction.CurrentSlot.ForgerCommitment - s2, err := NewSynchronizer(client, historyDB, stateDB, Config{ + s2, err := NewSynchronizer(client, historyDB, l2DB, stateDB, Config{ StatsRefreshPeriod: 0 * time.Second, }) require.NoError(t, err) diff --git a/test/ethclient.go b/test/ethclient.go index e8c5208..650627e 100644 --- a/test/ethclient.go +++ b/test/ethclient.go @@ -1897,12 +1897,16 @@ func (c *Client) CtlAddBlocks(blocks []common.BlockData) (err error) { } c.CtlSetAddr(auction.Vars.BootCoordinator) for _, batch := range block.Rollup.Batches { + auths := make([][]byte, len(batch.L1CoordinatorTxs)) + for i := range auths { + auths[i] = make([]byte, 65) + } if _, err := c.RollupForgeBatch(ð.RollupForgeBatchArgs{ NewLastIdx: batch.Batch.LastIdx, NewStRoot: batch.Batch.StateRoot, NewExitRoot: batch.Batch.ExitRoot, L1CoordinatorTxs: batch.L1CoordinatorTxs, - L1CoordinatorTxsAuths: [][]byte{}, // Intentionally empty + L1CoordinatorTxsAuths: auths, L2TxsData: batch.L2Txs, FeeIdxCoordinator: batch.Batch.FeeIdxsCoordinator, // Circuit selector