Merge pull request #611 from hermeznetwork/feature/sync-l1-account-creation-auth Synchronize the AccountCreationAuths from L1CoordinatorTxs
@@ -206,7 +206,7 @@ }
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, })
@@ -74,6 +74,16 @@ )
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)
@@ -725,6 +725,43 @@ assert.Equal(t, 0, offset)
} } +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 {
@@ -220,7 +220,19 @@ if err != nil {
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 @@ WDelayer: *sync.WDelayerConstants(),
} 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) {
@@ -11,6 +11,7 @@
"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 @@ }
// 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 @@ s := &Synchronizer{
ethClient: ethClient, consts: consts, historyDB: historyDB, + l2DB: l2DB, stateDB: stateDB, cfg: cfg, initVars: *initVars,@@ -657,7 +660,7 @@ hasBatch := false
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 @@ }
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,7 +916,28 @@ }
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,
@@ -15,6 +15,7 @@ ethCommon "github.com/ethereum/go-ethereum/common"
"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 @@ }
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 @@ historyDB := historydb.NewHistoryDB(db, db, nil)
// 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 @@ //
// Setup // - stateDB, historyDB := newTestModules(t) + stateDB, historyDB, l2DB := newTestModules(t) // Init eth client var timer timer@@ -347,7 +351,7 @@ bootCoordAddr := clientSetup.AuctionVariables.BootCoordinator
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 @@ assertEqualAccountsHistoryDBStateDB(t, dbAccounts, sdbAccounts)
} func TestSyncForgerCommitment(t *testing.T) { - stateDB, historyDB := newTestModules(t) + stateDB, historyDB, l2DB := newTestModules(t) // Init eth client var timer timer@@ -740,7 +744,7 @@ bootCoordAddr := clientSetup.AuctionVariables.BootCoordinator
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 @@ stats := s.Stats()
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)
@@ -1897,12 +1897,16 @@ }
} 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