diff --git a/db/kvdb/kvdb.go b/db/kvdb/kvdb.go index 5a9825d..11a8939 100644 --- a/db/kvdb/kvdb.go +++ b/db/kvdb/kvdb.go @@ -61,13 +61,13 @@ func (k *Last) setNew() error { defer k.rw.Unlock() if k.db != nil { k.db.Close() + k.db = nil } lastPath := path.Join(k.path, PathLast) - err := os.RemoveAll(lastPath) - if err != nil { + if err := os.RemoveAll(lastPath); err != nil { return tracerr.Wrap(err) } - db, err := pebble.NewPebbleStorage(path.Join(k.path, lastPath), false) + db, err := pebble.NewPebbleStorage(lastPath, false) if err != nil { return tracerr.Wrap(err) } @@ -80,6 +80,7 @@ func (k *Last) set(kvdb *KVDB, batchNum common.BatchNum) error { defer k.rw.Unlock() if k.db != nil { k.db.Close() + k.db = nil } lastPath := path.Join(k.path, PathLast) if err := kvdb.MakeCheckpointFromTo(batchNum, lastPath); err != nil { @@ -96,7 +97,10 @@ func (k *Last) set(kvdb *KVDB, batchNum common.BatchNum) error { func (k *Last) close() { k.rw.Lock() defer k.rw.Unlock() - k.db.Close() + if k.db != nil { + k.db.Close() + k.db = nil + } } // NewKVDB creates a new KVDB, allowing to use an in-memory or in-disk storage. @@ -166,14 +170,12 @@ func (kvdb *KVDB) Reset(batchNum common.BatchNum) error { func (kvdb *KVDB) reset(batchNum common.BatchNum, closeCurrent bool) error { currentPath := path.Join(kvdb.path, PathCurrent) - if closeCurrent { - if err := kvdb.db.Pebble().Close(); err != nil { - return tracerr.Wrap(err) - } + if closeCurrent && kvdb.db != nil { + kvdb.db.Close() + kvdb.db = nil } // remove 'current' - err := os.RemoveAll(currentPath) - if err != nil { + if err := os.RemoveAll(currentPath); err != nil { return tracerr.Wrap(err) } // remove all checkpoints > batchNum @@ -249,13 +251,13 @@ func (kvdb *KVDB) ResetFromSynchronizer(batchNum common.BatchNum, synchronizerKV } currentPath := path.Join(kvdb.path, PathCurrent) - if err := kvdb.db.Pebble().Close(); err != nil { - return tracerr.Wrap(err) + if kvdb.db != nil { + kvdb.db.Close() + kvdb.db = nil } // remove 'current' - err := os.RemoveAll(currentPath) - if err != nil { + if err := os.RemoveAll(currentPath); err != nil { return tracerr.Wrap(err) } // remove all checkpoints @@ -394,8 +396,7 @@ func (kvdb *KVDB) MakeCheckpoint() error { // if checkpoint BatchNum already exist in disk, delete it if _, err := os.Stat(checkpointPath); !os.IsNotExist(err) { - err := os.RemoveAll(checkpointPath) - if err != nil { + if err := os.RemoveAll(checkpointPath); err != nil { return tracerr.Wrap(err) } } else if err != nil && !os.IsNotExist(err) { @@ -501,8 +502,7 @@ func (kvdb *KVDB) MakeCheckpointFromTo(fromBatchNum common.BatchNum, dest string func pebbleMakeCheckpoint(source, dest string) error { // Remove dest folder (if it exists) before doing the checkpoint if _, err := os.Stat(dest); !os.IsNotExist(err) { - err := os.RemoveAll(dest) - if err != nil { + if err := os.RemoveAll(dest); err != nil { return tracerr.Wrap(err) } } else if err != nil && !os.IsNotExist(err) { @@ -513,12 +513,7 @@ func pebbleMakeCheckpoint(source, dest string) error { if err != nil { return tracerr.Wrap(err) } - defer func() { - errClose := sto.Pebble().Close() - if errClose != nil { - log.Errorw("Pebble.Close", "err", errClose) - } - }() + defer sto.Close() // execute Checkpoint err = sto.Pebble().Checkpoint(dest) @@ -531,6 +526,9 @@ func pebbleMakeCheckpoint(source, dest string) error { // Close the DB func (kvdb *KVDB) Close() { - kvdb.db.Close() + if kvdb.db != nil { + kvdb.db.Close() + kvdb.db = nil + } kvdb.last.close() } diff --git a/db/statedb/statedb.go b/db/statedb/statedb.go index ab3c973..74abea5 100644 --- a/db/statedb/statedb.go +++ b/db/statedb/statedb.go @@ -230,8 +230,8 @@ func (s *StateDB) SetCurrentIdx(idx common.Idx) error { // those checkpoints will remain in the storage, and eventually will be // deleted when MakeCheckpoint overwrites them. func (s *StateDB) Reset(batchNum common.BatchNum) error { - err := s.db.Reset(batchNum) - if err != nil { + log.Debugw("Making StateDB Reset", "batch", batchNum, "type", s.Typ) + if err := s.db.Reset(batchNum); err != nil { return tracerr.Wrap(err) } if s.MT != nil { @@ -242,7 +242,6 @@ func (s *StateDB) Reset(batchNum common.BatchNum) error { } s.MT = mt } - log.Debugw("Making StateDB Reset", "batch", batchNum) return nil } @@ -478,13 +477,13 @@ func NewLocalStateDB(path string, keep int, synchronizerDB *StateDB, typ TypeSta // If fromSynchronizer is false, get the state from LocalStateDB checkpoints. func (l *LocalStateDB) Reset(batchNum common.BatchNum, fromSynchronizer bool) error { if fromSynchronizer { - err := l.db.ResetFromSynchronizer(batchNum, l.synchronizerStateDB.db) - if err != nil { + if err := l.db.ResetFromSynchronizer(batchNum, l.synchronizerStateDB.db); err != nil { return tracerr.Wrap(err) } // open the MT for the current s.db if l.MT != nil { - mt, err := merkletree.NewMerkleTree(l.db.StorageWithPrefix(PrefixKeyMT), l.MT.MaxLevels()) + mt, err := merkletree.NewMerkleTree(l.db.StorageWithPrefix(PrefixKeyMT), + l.MT.MaxLevels()) if err != nil { return tracerr.Wrap(err) } diff --git a/db/statedb/statedb_test.go b/db/statedb/statedb_test.go index ad136fe..999cf8d 100644 --- a/db/statedb/statedb_test.go +++ b/db/statedb/statedb_test.go @@ -116,7 +116,7 @@ func TestNewStateDBIntermediateState(t *testing.T) { bn, err := sdb.getCurrentBatch() require.NoError(t, err) assert.Equal(t, common.BatchNum(0), bn) - err = sdb.db.MakeCheckpoint() + err = sdb.MakeCheckpoint() require.NoError(t, err) bn, err = sdb.getCurrentBatch() require.NoError(t, err) @@ -399,14 +399,12 @@ func TestCheckpoints(t *testing.T) { err = ldb2.Reset(4, true) require.NoError(t, err) // check that currentBatch is 4 after the Reset - cb, err = ldb2.db.GetCurrentBatch() - require.NoError(t, err) + cb = ldb2.CurrentBatch() assert.Equal(t, common.BatchNum(4), cb) // advance one checkpoint in ldb2 - err = ldb2.db.MakeCheckpoint() - require.NoError(t, err) - cb, err = ldb2.db.GetCurrentBatch() + err = ldb2.MakeCheckpoint() require.NoError(t, err) + cb = ldb2.CurrentBatch() assert.Equal(t, common.BatchNum(5), cb) debug := false @@ -624,3 +622,24 @@ func TestCurrentIdx(t *testing.T) { idx = sdb.CurrentIdx() assert.Equal(t, common.Idx(255), idx) } + +func TestResetFromBadCheckpoint(t *testing.T) { + dir, err := ioutil.TempDir("", "tmpdb") + require.NoError(t, err) + defer require.NoError(t, os.RemoveAll(dir)) + + keep := 16 + sdb, err := NewStateDB(dir, keep, TypeSynchronizer, 32) + require.NoError(t, err) + + err = sdb.MakeCheckpoint() + require.NoError(t, err) + err = sdb.MakeCheckpoint() + require.NoError(t, err) + err = sdb.MakeCheckpoint() + require.NoError(t, err) + + // reset from a checkpoint that doesn't exist + err = sdb.Reset(10) + require.Error(t, err) +} diff --git a/eth/auction.go b/eth/auction.go index 73592a9..eb8e2fc 100644 --- a/eth/auction.go +++ b/eth/auction.go @@ -254,7 +254,7 @@ type AuctionInterface interface { // AuctionConstants() (*common.AuctionConstants, error) - AuctionEventsByBlock(blockNum int64) (*AuctionEvents, *ethCommon.Hash, error) + AuctionEventsByBlock(blockNum int64, blockHash *ethCommon.Hash) (*AuctionEvents, error) AuctionEventInit() (*AuctionEventInitialize, int64, error) } @@ -797,15 +797,22 @@ func (c *AuctionClient) AuctionEventInit() (*AuctionEventInitialize, int64, erro } // AuctionEventsByBlock returns the events in a block that happened in the -// Auction Smart Contract and the blockHash where the eents happened. If there -// are no events in that block, blockHash is nil. -func (c *AuctionClient) AuctionEventsByBlock(blockNum int64) (*AuctionEvents, *ethCommon.Hash, error) { +// Auction Smart Contract. +// To query by blockNum, set blockNum >= 0 and blockHash == nil. +// To query by blockHash, set blockNum == -1 and blockHash != nil. +// If there are no events in that block the result is nil. +func (c *AuctionClient) AuctionEventsByBlock(blockNum int64, + blockHash *ethCommon.Hash) (*AuctionEvents, error) { var auctionEvents AuctionEvents - var blockHash *ethCommon.Hash + var blockNumBigInt *big.Int + if blockNum >= 0 { + blockNumBigInt = big.NewInt(blockNum) + } query := ethereum.FilterQuery{ - FromBlock: big.NewInt(blockNum), - ToBlock: big.NewInt(blockNum), + BlockHash: blockHash, + FromBlock: blockNumBigInt, + ToBlock: blockNumBigInt, Addresses: []ethCommon.Address{ c.address, }, @@ -814,15 +821,16 @@ func (c *AuctionClient) AuctionEventsByBlock(blockNum int64) (*AuctionEvents, *e logs, err := c.client.client.FilterLogs(context.TODO(), query) if err != nil { - return nil, nil, tracerr.Wrap(err) + return nil, tracerr.Wrap(err) } - if len(logs) > 0 { - blockHash = &logs[0].BlockHash + if len(logs) == 0 { + return nil, nil } + for _, vLog := range logs { - if vLog.BlockHash != *blockHash { + if blockHash != nil && vLog.BlockHash != *blockHash { log.Errorw("Block hash mismatch", "expected", blockHash.String(), "got", vLog.BlockHash.String()) - return nil, nil, tracerr.Wrap(ErrBlockHashMismatchEvent) + return nil, tracerr.Wrap(ErrBlockHashMismatchEvent) } switch vLog.Topics[0] { case logAuctionNewBid: @@ -833,7 +841,7 @@ func (c *AuctionClient) AuctionEventsByBlock(blockNum int64) (*AuctionEvents, *e } var newBid AuctionEventNewBid if err := c.contractAbi.UnpackIntoInterface(&auxNewBid, "NewBid", vLog.Data); err != nil { - return nil, nil, tracerr.Wrap(err) + return nil, tracerr.Wrap(err) } newBid.BidAmount = auxNewBid.BidAmount newBid.Slot = new(big.Int).SetBytes(vLog.Topics[1][:]).Int64() @@ -842,19 +850,19 @@ func (c *AuctionClient) AuctionEventsByBlock(blockNum int64) (*AuctionEvents, *e case logAuctionNewSlotDeadline: var newSlotDeadline AuctionEventNewSlotDeadline if err := c.contractAbi.UnpackIntoInterface(&newSlotDeadline, "NewSlotDeadline", vLog.Data); err != nil { - return nil, nil, tracerr.Wrap(err) + return nil, tracerr.Wrap(err) } auctionEvents.NewSlotDeadline = append(auctionEvents.NewSlotDeadline, newSlotDeadline) case logAuctionNewClosedAuctionSlots: var newClosedAuctionSlots AuctionEventNewClosedAuctionSlots if err := c.contractAbi.UnpackIntoInterface(&newClosedAuctionSlots, "NewClosedAuctionSlots", vLog.Data); err != nil { - return nil, nil, tracerr.Wrap(err) + return nil, tracerr.Wrap(err) } auctionEvents.NewClosedAuctionSlots = append(auctionEvents.NewClosedAuctionSlots, newClosedAuctionSlots) case logAuctionNewOutbidding: var newOutbidding AuctionEventNewOutbidding if err := c.contractAbi.UnpackIntoInterface(&newOutbidding, "NewOutbidding", vLog.Data); err != nil { - return nil, nil, tracerr.Wrap(err) + return nil, tracerr.Wrap(err) } auctionEvents.NewOutbidding = append(auctionEvents.NewOutbidding, newOutbidding) case logAuctionNewDonationAddress: @@ -864,26 +872,26 @@ func (c *AuctionClient) AuctionEventsByBlock(blockNum int64) (*AuctionEvents, *e case logAuctionNewBootCoordinator: var newBootCoordinator AuctionEventNewBootCoordinator if err := c.contractAbi.UnpackIntoInterface(&newBootCoordinator, "NewBootCoordinator", vLog.Data); err != nil { - return nil, nil, tracerr.Wrap(err) + return nil, tracerr.Wrap(err) } newBootCoordinator.NewBootCoordinator = ethCommon.BytesToAddress(vLog.Topics[1].Bytes()) auctionEvents.NewBootCoordinator = append(auctionEvents.NewBootCoordinator, newBootCoordinator) case logAuctionNewOpenAuctionSlots: var newOpenAuctionSlots AuctionEventNewOpenAuctionSlots if err := c.contractAbi.UnpackIntoInterface(&newOpenAuctionSlots, "NewOpenAuctionSlots", vLog.Data); err != nil { - return nil, nil, tracerr.Wrap(err) + return nil, tracerr.Wrap(err) } auctionEvents.NewOpenAuctionSlots = append(auctionEvents.NewOpenAuctionSlots, newOpenAuctionSlots) case logAuctionNewAllocationRatio: var newAllocationRatio AuctionEventNewAllocationRatio if err := c.contractAbi.UnpackIntoInterface(&newAllocationRatio, "NewAllocationRatio", vLog.Data); err != nil { - return nil, nil, tracerr.Wrap(err) + return nil, tracerr.Wrap(err) } auctionEvents.NewAllocationRatio = append(auctionEvents.NewAllocationRatio, newAllocationRatio) case logAuctionSetCoordinator: var setCoordinator AuctionEventSetCoordinator if err := c.contractAbi.UnpackIntoInterface(&setCoordinator, "SetCoordinator", vLog.Data); err != nil { - return nil, nil, tracerr.Wrap(err) + return nil, tracerr.Wrap(err) } setCoordinator.BidderAddress = ethCommon.BytesToAddress(vLog.Topics[1].Bytes()) setCoordinator.ForgerAddress = ethCommon.BytesToAddress(vLog.Topics[2].Bytes()) @@ -891,7 +899,7 @@ func (c *AuctionClient) AuctionEventsByBlock(blockNum int64) (*AuctionEvents, *e case logAuctionNewForgeAllocated: var newForgeAllocated AuctionEventNewForgeAllocated if err := c.contractAbi.UnpackIntoInterface(&newForgeAllocated, "NewForgeAllocated", vLog.Data); err != nil { - return nil, nil, tracerr.Wrap(err) + return nil, tracerr.Wrap(err) } newForgeAllocated.Bidder = ethCommon.BytesToAddress(vLog.Topics[1].Bytes()) newForgeAllocated.Forger = ethCommon.BytesToAddress(vLog.Topics[2].Bytes()) @@ -904,7 +912,7 @@ func (c *AuctionClient) AuctionEventsByBlock(blockNum int64) (*AuctionEvents, *e } var newDefaultSlotSetBid AuctionEventNewDefaultSlotSetBid if err := c.contractAbi.UnpackIntoInterface(&auxNewDefaultSlotSetBid, "NewDefaultSlotSetBid", vLog.Data); err != nil { - return nil, nil, tracerr.Wrap(err) + return nil, tracerr.Wrap(err) } newDefaultSlotSetBid.NewInitialMinBid = auxNewDefaultSlotSetBid.NewInitialMinBid newDefaultSlotSetBid.SlotSet = auxNewDefaultSlotSetBid.SlotSet.Int64() @@ -917,11 +925,11 @@ func (c *AuctionClient) AuctionEventsByBlock(blockNum int64) (*AuctionEvents, *e case logAuctionHEZClaimed: var HEZClaimed AuctionEventHEZClaimed if err := c.contractAbi.UnpackIntoInterface(&HEZClaimed, "HEZClaimed", vLog.Data); err != nil { - return nil, nil, tracerr.Wrap(err) + return nil, tracerr.Wrap(err) } HEZClaimed.Owner = ethCommon.BytesToAddress(vLog.Topics[1].Bytes()) auctionEvents.HEZClaimed = append(auctionEvents.HEZClaimed, HEZClaimed) } } - return &auctionEvents, blockHash, nil + return &auctionEvents, nil } diff --git a/eth/auction_test.go b/eth/auction_test.go index 0ab7342..51fb894 100644 --- a/eth/auction_test.go +++ b/eth/auction_test.go @@ -88,7 +88,7 @@ func TestAuctionSetSlotDeadline(t *testing.T) { assert.Equal(t, newSlotDeadline, slotDeadline) currentBlockNum, err := auctionClientTest.client.EthLastBlock() require.Nil(t, err) - auctionEvents, _, err := auctionClientTest.AuctionEventsByBlock(currentBlockNum) + auctionEvents, err := auctionClientTest.AuctionEventsByBlock(currentBlockNum, nil) require.Nil(t, err) assert.Equal(t, newSlotDeadline, auctionEvents.NewSlotDeadline[0].NewSlotDeadline) } @@ -109,7 +109,7 @@ func TestAuctionSetOpenAuctionSlots(t *testing.T) { assert.Equal(t, newOpenAuctionSlots, openAuctionSlots) currentBlockNum, err := auctionClientTest.client.EthLastBlock() require.Nil(t, err) - auctionEvents, _, err := auctionClientTest.AuctionEventsByBlock(currentBlockNum) + auctionEvents, err := auctionClientTest.AuctionEventsByBlock(currentBlockNum, nil) require.Nil(t, err) assert.Equal(t, newOpenAuctionSlots, auctionEvents.NewOpenAuctionSlots[0].NewOpenAuctionSlots) } @@ -130,7 +130,7 @@ func TestAuctionSetClosedAuctionSlots(t *testing.T) { assert.Equal(t, newClosedAuctionSlots, closedAuctionSlots) currentBlockNum, err := auctionClientTest.client.EthLastBlock() require.Nil(t, err) - auctionEvents, _, err := auctionClientTest.AuctionEventsByBlock(currentBlockNum) + auctionEvents, err := auctionClientTest.AuctionEventsByBlock(currentBlockNum, nil) require.Nil(t, err) assert.Equal(t, newClosedAuctionSlots, auctionEvents.NewClosedAuctionSlots[0].NewClosedAuctionSlots) _, err = auctionClientTest.AuctionSetClosedAuctionSlots(closedAuctionSlots) @@ -153,7 +153,7 @@ func TestAuctionSetOutbidding(t *testing.T) { assert.Equal(t, newOutbidding, outbidding) currentBlockNum, err := auctionClientTest.client.EthLastBlock() require.Nil(t, err) - auctionEvents, _, err := auctionClientTest.AuctionEventsByBlock(currentBlockNum) + auctionEvents, err := auctionClientTest.AuctionEventsByBlock(currentBlockNum, nil) require.Nil(t, err) assert.Equal(t, newOutbidding, auctionEvents.NewOutbidding[0].NewOutbidding) _, err = auctionClientTest.AuctionSetOutbidding(outbiddingConst) @@ -176,7 +176,7 @@ func TestAuctionSetAllocationRatio(t *testing.T) { assert.Equal(t, newAllocationRatio, allocationRatio) currentBlockNum, err := auctionClientTest.client.EthLastBlock() require.Nil(t, err) - auctionEvents, _, err := auctionClientTest.AuctionEventsByBlock(currentBlockNum) + auctionEvents, err := auctionClientTest.AuctionEventsByBlock(currentBlockNum, nil) require.Nil(t, err) assert.Equal(t, newAllocationRatio, auctionEvents.NewAllocationRatio[0].NewAllocationRatio) _, err = auctionClientTest.AuctionSetAllocationRatio(allocationRatioConst) @@ -205,7 +205,7 @@ func TestAuctionSetDonationAddress(t *testing.T) { assert.Equal(t, &newDonationAddress, donationAddress) currentBlockNum, err := auctionClientTest.client.EthLastBlock() require.Nil(t, err) - auctionEvents, _, err := auctionClientTest.AuctionEventsByBlock(currentBlockNum) + auctionEvents, err := auctionClientTest.AuctionEventsByBlock(currentBlockNum, nil) require.Nil(t, err) assert.Equal(t, newDonationAddress, auctionEvents.NewDonationAddress[0].NewDonationAddress) _, err = auctionClientTest.AuctionSetDonationAddress(donationAddressConst) @@ -224,7 +224,7 @@ func TestAuctionSetBootCoordinator(t *testing.T) { assert.Equal(t, &newBootCoordinator, bootCoordinator) currentBlockNum, err := auctionClientTest.client.EthLastBlock() require.Nil(t, err) - auctionEvents, _, err := auctionClientTest.AuctionEventsByBlock(currentBlockNum) + auctionEvents, err := auctionClientTest.AuctionEventsByBlock(currentBlockNum, nil) require.Nil(t, err) assert.Equal(t, newBootCoordinator, auctionEvents.NewBootCoordinator[0].NewBootCoordinator) assert.Equal(t, newBootCoordinatorURL, auctionEvents.NewBootCoordinator[0].NewBootCoordinatorURL) @@ -261,7 +261,7 @@ func TestAuctionChangeDefaultSlotSetBid(t *testing.T) { assert.Equal(t, minBid, newInitialMinBid) currentBlockNum, err := auctionClientTest.client.EthLastBlock() require.Nil(t, err) - auctionEvents, _, err := auctionClientTest.AuctionEventsByBlock(currentBlockNum) + auctionEvents, err := auctionClientTest.AuctionEventsByBlock(currentBlockNum, nil) require.Nil(t, err) assert.Equal(t, slotSet, auctionEvents.NewDefaultSlotSetBid[0].SlotSet) assert.Equal(t, newInitialMinBid, auctionEvents.NewDefaultSlotSetBid[0].NewInitialMinBid) @@ -287,7 +287,7 @@ func TestAuctionRegisterCoordinator(t *testing.T) { require.Nil(t, err) currentBlockNum, err := auctionClientTest.client.EthLastBlock() require.Nil(t, err) - auctionEvents, _, err := auctionClientTest.AuctionEventsByBlock(currentBlockNum) + auctionEvents, err := auctionClientTest.AuctionEventsByBlock(currentBlockNum, nil) require.Nil(t, err) assert.Equal(t, forgerAddress, auctionEvents.SetCoordinator[0].ForgerAddress) assert.Equal(t, bidderAddress, auctionEvents.SetCoordinator[0].BidderAddress) @@ -306,7 +306,7 @@ func TestAuctionBid(t *testing.T) { require.Nil(t, err) currentBlockNum, err := auctionClientTest.client.EthLastBlock() require.Nil(t, err) - auctionEvents, _, err := auctionClientTest.AuctionEventsByBlock(currentBlockNum) + auctionEvents, err := auctionClientTest.AuctionEventsByBlock(currentBlockNum, nil) require.Nil(t, err) assert.Equal(t, bidAmount, auctionEvents.NewBid[0].BidAmount) assert.Equal(t, bidderAddress, auctionEvents.NewBid[0].Bidder) @@ -346,7 +346,7 @@ func TestAuctionMultiBid(t *testing.T) { require.Nil(t, err) currentBlockNum, err := auctionClientTest.client.EthLastBlock() require.Nil(t, err) - auctionEvents, _, err := auctionClientTest.AuctionEventsByBlock(currentBlockNum) + auctionEvents, err := auctionClientTest.AuctionEventsByBlock(currentBlockNum, nil) require.Nil(t, err) assert.Equal(t, bidderAddress, auctionEvents.NewBid[0].Bidder) assert.Equal(t, currentSlot+4, auctionEvents.NewBid[0].Slot) @@ -376,7 +376,7 @@ func TestAuctionClaimHEZ(t *testing.T) { require.Nil(t, err) currentBlockNum, err := auctionClientTest.client.EthLastBlock() require.Nil(t, err) - auctionEvents, _, err := auctionClientTest.AuctionEventsByBlock(currentBlockNum) + auctionEvents, err := auctionClientTest.AuctionEventsByBlock(currentBlockNum, nil) require.Nil(t, err) assert.Equal(t, amount, auctionEvents.HEZClaimed[0].Amount) assert.Equal(t, governanceAddressConst, auctionEvents.HEZClaimed[0].Owner) diff --git a/eth/rollup.go b/eth/rollup.go index 3a1ad51..0989086 100644 --- a/eth/rollup.go +++ b/eth/rollup.go @@ -264,7 +264,7 @@ type RollupInterface interface { // RollupConstants() (*common.RollupConstants, error) - RollupEventsByBlock(blockNum int64) (*RollupEvents, *ethCommon.Hash, error) + RollupEventsByBlock(blockNum int64, blockHash *ethCommon.Hash) (*RollupEvents, error) RollupForgeBatchArgs(ethCommon.Hash, uint16) (*RollupForgeBatchArgs, *ethCommon.Address, error) RollupEventInit() (*RollupEventInitialize, int64, error) } @@ -735,31 +735,40 @@ func (c *RollupClient) RollupEventInit() (*RollupEventInitialize, int64, error) return &rollupInit, int64(vLog.BlockNumber), tracerr.Wrap(err) } -// RollupEventsByBlock returns the events in a block that happened in the Rollup Smart Contract -func (c *RollupClient) RollupEventsByBlock(blockNum int64) (*RollupEvents, *ethCommon.Hash, error) { +// RollupEventsByBlock returns the events in a block that happened in the +// Rollup Smart Contract. +// To query by blockNum, set blockNum >= 0 and blockHash == nil. +// To query by blockHash, set blockNum == -1 and blockHash != nil. +// If there are no events in that block the result is nil. +func (c *RollupClient) RollupEventsByBlock(blockNum int64, + blockHash *ethCommon.Hash) (*RollupEvents, error) { var rollupEvents RollupEvents - var blockHash *ethCommon.Hash + var blockNumBigInt *big.Int + if blockNum >= 0 { + blockNumBigInt = big.NewInt(blockNum) + } query := ethereum.FilterQuery{ - FromBlock: big.NewInt(blockNum), - ToBlock: big.NewInt(blockNum), + BlockHash: blockHash, + FromBlock: blockNumBigInt, + ToBlock: blockNumBigInt, Addresses: []ethCommon.Address{ c.address, }, - BlockHash: nil, - Topics: [][]ethCommon.Hash{}, + Topics: [][]ethCommon.Hash{}, } logs, err := c.client.client.FilterLogs(context.Background(), query) if err != nil { - return nil, nil, tracerr.Wrap(err) + return nil, tracerr.Wrap(err) } - if len(logs) > 0 { - blockHash = &logs[0].BlockHash + if len(logs) == 0 { + return nil, nil } + for _, vLog := range logs { - if vLog.BlockHash != *blockHash { + if blockHash != nil && vLog.BlockHash != *blockHash { log.Errorw("Block hash mismatch", "expected", blockHash.String(), "got", vLog.BlockHash.String()) - return nil, nil, tracerr.Wrap(ErrBlockHashMismatchEvent) + return nil, tracerr.Wrap(ErrBlockHashMismatchEvent) } switch vLog.Topics[0] { case logHermezL1UserTxEvent: @@ -767,11 +776,11 @@ func (c *RollupClient) RollupEventsByBlock(blockNum int64) (*RollupEvents, *ethC var L1UserTx RollupEventL1UserTx err := c.contractAbi.UnpackIntoInterface(&L1UserTxAux, "L1UserTxEvent", vLog.Data) if err != nil { - return nil, nil, tracerr.Wrap(err) + return nil, tracerr.Wrap(err) } L1Tx, err := common.L1UserTxFromBytes(L1UserTxAux.L1UserTx) if err != nil { - return nil, nil, tracerr.Wrap(err) + return nil, tracerr.Wrap(err) } toForgeL1TxsNum := new(big.Int).SetBytes(vLog.Topics[1][:]).Int64() L1Tx.ToForgeL1TxsNum = &toForgeL1TxsNum @@ -783,7 +792,7 @@ func (c *RollupClient) RollupEventsByBlock(blockNum int64) (*RollupEvents, *ethC var addToken RollupEventAddToken err := c.contractAbi.UnpackIntoInterface(&addToken, "AddToken", vLog.Data) if err != nil { - return nil, nil, tracerr.Wrap(err) + return nil, tracerr.Wrap(err) } addToken.TokenAddress = ethCommon.BytesToAddress(vLog.Topics[1].Bytes()) rollupEvents.AddToken = append(rollupEvents.AddToken, addToken) @@ -791,7 +800,7 @@ func (c *RollupClient) RollupEventsByBlock(blockNum int64) (*RollupEvents, *ethC var forgeBatch RollupEventForgeBatch err := c.contractAbi.UnpackIntoInterface(&forgeBatch, "ForgeBatch", vLog.Data) if err != nil { - return nil, nil, tracerr.Wrap(err) + return nil, tracerr.Wrap(err) } forgeBatch.BatchNum = new(big.Int).SetBytes(vLog.Topics[1][:]).Int64() forgeBatch.EthTxHash = vLog.TxHash @@ -803,7 +812,7 @@ func (c *RollupClient) RollupEventsByBlock(blockNum int64) (*RollupEvents, *ethC } err := c.contractAbi.UnpackIntoInterface(&updateForgeL1L2BatchTimeout, "UpdateForgeL1L2BatchTimeout", vLog.Data) if err != nil { - return nil, nil, tracerr.Wrap(err) + return nil, tracerr.Wrap(err) } rollupEvents.UpdateForgeL1L2BatchTimeout = append(rollupEvents.UpdateForgeL1L2BatchTimeout, RollupEventUpdateForgeL1L2BatchTimeout{ @@ -813,7 +822,7 @@ func (c *RollupClient) RollupEventsByBlock(blockNum int64) (*RollupEvents, *ethC var updateFeeAddToken RollupEventUpdateFeeAddToken err := c.contractAbi.UnpackIntoInterface(&updateFeeAddToken, "UpdateFeeAddToken", vLog.Data) if err != nil { - return nil, nil, tracerr.Wrap(err) + return nil, tracerr.Wrap(err) } rollupEvents.UpdateFeeAddToken = append(rollupEvents.UpdateFeeAddToken, updateFeeAddToken) case logHermezWithdrawEvent: @@ -831,7 +840,7 @@ func (c *RollupClient) RollupEventsByBlock(blockNum int64) (*RollupEvents, *ethC var updateBucketWithdraw RollupEventUpdateBucketWithdraw err := c.contractAbi.UnpackIntoInterface(&updateBucketWithdrawAux, "UpdateBucketWithdraw", vLog.Data) if err != nil { - return nil, nil, tracerr.Wrap(err) + return nil, tracerr.Wrap(err) } updateBucketWithdraw.Withdrawals = updateBucketWithdrawAux.Withdrawals updateBucketWithdraw.NumBucket = int(new(big.Int).SetBytes(vLog.Topics[1][:]).Int64()) @@ -842,7 +851,7 @@ func (c *RollupClient) RollupEventsByBlock(blockNum int64) (*RollupEvents, *ethC var withdrawalDelay RollupEventUpdateWithdrawalDelay err := c.contractAbi.UnpackIntoInterface(&withdrawalDelay, "UpdateWithdrawalDelay", vLog.Data) if err != nil { - return nil, nil, tracerr.Wrap(err) + return nil, tracerr.Wrap(err) } rollupEvents.UpdateWithdrawalDelay = append(rollupEvents.UpdateWithdrawalDelay, withdrawalDelay) case logHermezUpdateBucketsParameters: @@ -850,7 +859,7 @@ func (c *RollupClient) RollupEventsByBlock(blockNum int64) (*RollupEvents, *ethC var bucketsParameters RollupEventUpdateBucketsParameters err := c.contractAbi.UnpackIntoInterface(&bucketsParametersAux, "UpdateBucketsParameters", vLog.Data) if err != nil { - return nil, nil, tracerr.Wrap(err) + return nil, tracerr.Wrap(err) } for i, bucket := range bucketsParametersAux.ArrayBuckets { bucketsParameters.ArrayBuckets[i].CeilUSD = bucket[0] @@ -863,7 +872,7 @@ func (c *RollupClient) RollupEventsByBlock(blockNum int64) (*RollupEvents, *ethC var tokensExchange RollupEventUpdateTokenExchange err := c.contractAbi.UnpackIntoInterface(&tokensExchange, "UpdateTokenExchange", vLog.Data) if err != nil { - return nil, nil, tracerr.Wrap(err) + return nil, tracerr.Wrap(err) } rollupEvents.UpdateTokenExchange = append(rollupEvents.UpdateTokenExchange, tokensExchange) case logHermezSafeMode: @@ -885,7 +894,7 @@ func (c *RollupClient) RollupEventsByBlock(blockNum int64) (*RollupEvents, *ethC bucketsParameters) } } - return &rollupEvents, blockHash, nil + return &rollupEvents, nil } // RollupForgeBatchArgs returns the arguments used in a ForgeBatch call in the @@ -893,7 +902,7 @@ func (c *RollupClient) RollupEventsByBlock(blockNum int64) (*RollupEvents, *ethC func (c *RollupClient) RollupForgeBatchArgs(ethTxHash ethCommon.Hash, l1UserTxsLen uint16) (*RollupForgeBatchArgs, *ethCommon.Address, error) { tx, _, err := c.client.client.TransactionByHash(context.Background(), ethTxHash) if err != nil { - return nil, nil, tracerr.Wrap(err) + return nil, nil, tracerr.Wrap(fmt.Errorf("TransactionByHash: %w", err)) } txData := tx.Data() diff --git a/eth/rollup_test.go b/eth/rollup_test.go index 8f4b326..14c4cd3 100644 --- a/eth/rollup_test.go +++ b/eth/rollup_test.go @@ -91,7 +91,7 @@ func TestRollupAddToken(t *testing.T) { require.NoError(t, err) currentBlockNum, err := rollupClient.client.EthLastBlock() require.NoError(t, err) - rollupEvents, _, err := rollupClient.RollupEventsByBlock(currentBlockNum) + rollupEvents, err := rollupClient.RollupEventsByBlock(currentBlockNum, nil) require.NoError(t, err) assert.Equal(t, tokenHEZAddressConst, rollupEvents.AddToken[0].TokenAddress) @@ -174,7 +174,7 @@ func TestRollupForgeBatch(t *testing.T) { currentBlockNum, err = rollupClient.client.EthLastBlock() require.NoError(t, err) - rollupEvents, _, err := rollupClient.RollupEventsByBlock(currentBlockNum) + rollupEvents, err := rollupClient.RollupEventsByBlock(currentBlockNum, nil) require.NoError(t, err) assert.Equal(t, int64(1), rollupEvents.ForgeBatch[0].BatchNum) @@ -203,7 +203,7 @@ func TestRollupUpdateForgeL1L2BatchTimeout(t *testing.T) { currentBlockNum, err := rollupClient.client.EthLastBlock() require.NoError(t, err) - rollupEvents, _, err := rollupClient.RollupEventsByBlock(currentBlockNum) + rollupEvents, err := rollupClient.RollupEventsByBlock(currentBlockNum, nil) require.NoError(t, err) assert.Equal(t, newForgeL1L2BatchTimeout, rollupEvents.UpdateForgeL1L2BatchTimeout[0].NewForgeL1L2BatchTimeout) @@ -216,7 +216,7 @@ func TestRollupUpdateFeeAddToken(t *testing.T) { currentBlockNum, err := rollupClient.client.EthLastBlock() require.NoError(t, err) - rollupEvents, _, err := rollupClient.RollupEventsByBlock(currentBlockNum) + rollupEvents, err := rollupClient.RollupEventsByBlock(currentBlockNum, nil) require.NoError(t, err) assert.Equal(t, newFeeAddToken, rollupEvents.UpdateFeeAddToken[0].NewFeeAddToken) @@ -235,7 +235,7 @@ func TestRollupUpdateBucketsParameters(t *testing.T) { currentBlockNum, err := rollupClient.client.EthLastBlock() require.NoError(t, err) blockStampBucket = currentBlockNum - rollupEvents, _, err := rollupClient.RollupEventsByBlock(currentBlockNum) + rollupEvents, err := rollupClient.RollupEventsByBlock(currentBlockNum, nil) require.NoError(t, err) assert.Equal(t, bucketsParameters, rollupEvents.UpdateBucketsParameters[0].ArrayBuckets) } @@ -246,7 +246,7 @@ func TestRollupUpdateWithdrawalDelay(t *testing.T) { require.NoError(t, err) currentBlockNum, err := rollupClient.client.EthLastBlock() require.NoError(t, err) - rollupEvents, _, err := rollupClient.RollupEventsByBlock(currentBlockNum) + rollupEvents, err := rollupClient.RollupEventsByBlock(currentBlockNum, nil) require.NoError(t, err) assert.Equal(t, newWithdrawalDelay, int64(rollupEvents.UpdateWithdrawalDelay[0].NewWithdrawalDelay)) } @@ -263,7 +263,7 @@ func TestRollupUpdateTokenExchange(t *testing.T) { require.NoError(t, err) currentBlockNum, err := rollupClient.client.EthLastBlock() require.NoError(t, err) - rollupEvents, _, err := rollupClient.RollupEventsByBlock(currentBlockNum) + rollupEvents, err := rollupClient.RollupEventsByBlock(currentBlockNum, nil) require.NoError(t, err) assert.Equal(t, addressArray, rollupEvents.UpdateTokenExchange[0].AddressArray) assert.Equal(t, valueArray, rollupEvents.UpdateTokenExchange[0].ValueArray) @@ -292,7 +292,7 @@ func TestRollupL1UserTxETHCreateAccountDeposit(t *testing.T) { currentBlockNum, err := rollupClient.client.EthLastBlock() require.NoError(t, err) - rollupEvents, _, err := rollupClient.RollupEventsByBlock(currentBlockNum) + rollupEvents, err := rollupClient.RollupEventsByBlock(currentBlockNum, nil) require.NoError(t, err) assert.Equal(t, l1Tx.FromBJJ, rollupEvents.L1UserTx[0].L1UserTx.FromBJJ) assert.Equal(t, l1Tx.ToIdx, rollupEvents.L1UserTx[0].L1UserTx.ToIdx) @@ -324,7 +324,7 @@ func TestRollupL1UserTxERC20CreateAccountDeposit(t *testing.T) { currentBlockNum, err := rollupClient.client.EthLastBlock() require.NoError(t, err) - rollupEvents, _, err := rollupClient.RollupEventsByBlock(currentBlockNum) + rollupEvents, err := rollupClient.RollupEventsByBlock(currentBlockNum, nil) require.NoError(t, err) assert.Equal(t, l1Tx.FromBJJ, rollupEvents.L1UserTx[0].L1UserTx.FromBJJ) assert.Equal(t, l1Tx.ToIdx, rollupEvents.L1UserTx[0].L1UserTx.ToIdx) @@ -356,7 +356,7 @@ func TestRollupL1UserTxERC20PermitCreateAccountDeposit(t *testing.T) { currentBlockNum, err := rollupClient.client.EthLastBlock() require.NoError(t, err) - rollupEvents, _, err := rollupClient.RollupEventsByBlock(currentBlockNum) + rollupEvents, err := rollupClient.RollupEventsByBlock(currentBlockNum, nil) require.NoError(t, err) assert.Equal(t, l1Tx.FromBJJ, rollupEvents.L1UserTx[0].L1UserTx.FromBJJ) assert.Equal(t, l1Tx.ToIdx, rollupEvents.L1UserTx[0].L1UserTx.ToIdx) @@ -388,7 +388,7 @@ func TestRollupL1UserTxETHDeposit(t *testing.T) { currentBlockNum, err := rollupClient.client.EthLastBlock() require.NoError(t, err) - rollupEvents, _, err := rollupClient.RollupEventsByBlock(currentBlockNum) + rollupEvents, err := rollupClient.RollupEventsByBlock(currentBlockNum, nil) require.NoError(t, err) assert.Equal(t, l1Tx.ToIdx, rollupEvents.L1UserTx[0].L1UserTx.ToIdx) assert.Equal(t, l1Tx.DepositAmount, rollupEvents.L1UserTx[0].L1UserTx.DepositAmount) @@ -418,7 +418,7 @@ func TestRollupL1UserTxERC20Deposit(t *testing.T) { currentBlockNum, err := rollupClient.client.EthLastBlock() require.NoError(t, err) - rollupEvents, _, err := rollupClient.RollupEventsByBlock(currentBlockNum) + rollupEvents, err := rollupClient.RollupEventsByBlock(currentBlockNum, nil) require.NoError(t, err) assert.Equal(t, l1Tx.ToIdx, rollupEvents.L1UserTx[0].L1UserTx.ToIdx) assert.Equal(t, l1Tx.DepositAmount, rollupEvents.L1UserTx[0].L1UserTx.DepositAmount) @@ -447,7 +447,7 @@ func TestRollupL1UserTxERC20PermitDeposit(t *testing.T) { currentBlockNum, err := rollupClient.client.EthLastBlock() require.NoError(t, err) - rollupEvents, _, err := rollupClient.RollupEventsByBlock(currentBlockNum) + rollupEvents, err := rollupClient.RollupEventsByBlock(currentBlockNum, nil) require.NoError(t, err) assert.Equal(t, l1Tx.ToIdx, rollupEvents.L1UserTx[0].L1UserTx.ToIdx) assert.Equal(t, l1Tx.DepositAmount, rollupEvents.L1UserTx[0].L1UserTx.DepositAmount) @@ -478,7 +478,7 @@ func TestRollupL1UserTxETHDepositTransfer(t *testing.T) { currentBlockNum, err := rollupClient.client.EthLastBlock() require.NoError(t, err) - rollupEvents, _, err := rollupClient.RollupEventsByBlock(currentBlockNum) + rollupEvents, err := rollupClient.RollupEventsByBlock(currentBlockNum, nil) require.NoError(t, err) assert.Equal(t, l1Tx.ToIdx, rollupEvents.L1UserTx[0].L1UserTx.ToIdx) assert.Equal(t, l1Tx.DepositAmount, rollupEvents.L1UserTx[0].L1UserTx.DepositAmount) @@ -508,7 +508,7 @@ func TestRollupL1UserTxERC20DepositTransfer(t *testing.T) { currentBlockNum, err := rollupClient.client.EthLastBlock() require.NoError(t, err) - rollupEvents, _, err := rollupClient.RollupEventsByBlock(currentBlockNum) + rollupEvents, err := rollupClient.RollupEventsByBlock(currentBlockNum, nil) require.NoError(t, err) assert.Equal(t, l1Tx.ToIdx, rollupEvents.L1UserTx[0].L1UserTx.ToIdx) assert.Equal(t, l1Tx.DepositAmount, rollupEvents.L1UserTx[0].L1UserTx.DepositAmount) @@ -538,7 +538,7 @@ func TestRollupL1UserTxERC20PermitDepositTransfer(t *testing.T) { currentBlockNum, err := rollupClient.client.EthLastBlock() require.NoError(t, err) - rollupEvents, _, err := rollupClient.RollupEventsByBlock(currentBlockNum) + rollupEvents, err := rollupClient.RollupEventsByBlock(currentBlockNum, nil) require.NoError(t, err) assert.Equal(t, l1Tx.ToIdx, rollupEvents.L1UserTx[0].L1UserTx.ToIdx) assert.Equal(t, l1Tx.DepositAmount, rollupEvents.L1UserTx[0].L1UserTx.DepositAmount) @@ -569,7 +569,7 @@ func TestRollupL1UserTxETHCreateAccountDepositTransfer(t *testing.T) { currentBlockNum, err := rollupClient.client.EthLastBlock() require.NoError(t, err) - rollupEvents, _, err := rollupClient.RollupEventsByBlock(currentBlockNum) + rollupEvents, err := rollupClient.RollupEventsByBlock(currentBlockNum, nil) require.NoError(t, err) assert.Equal(t, l1Tx.ToIdx, rollupEvents.L1UserTx[0].L1UserTx.ToIdx) assert.Equal(t, l1Tx.DepositAmount, rollupEvents.L1UserTx[0].L1UserTx.DepositAmount) @@ -599,7 +599,7 @@ func TestRollupL1UserTxERC20CreateAccountDepositTransfer(t *testing.T) { currentBlockNum, err := rollupClient.client.EthLastBlock() require.NoError(t, err) - rollupEvents, _, err := rollupClient.RollupEventsByBlock(currentBlockNum) + rollupEvents, err := rollupClient.RollupEventsByBlock(currentBlockNum, nil) require.NoError(t, err) assert.Equal(t, l1Tx.ToIdx, rollupEvents.L1UserTx[0].L1UserTx.ToIdx) assert.Equal(t, l1Tx.DepositAmount, rollupEvents.L1UserTx[0].L1UserTx.DepositAmount) @@ -629,7 +629,7 @@ func TestRollupL1UserTxERC20PermitCreateAccountDepositTransfer(t *testing.T) { currentBlockNum, err := rollupClient.client.EthLastBlock() require.NoError(t, err) - rollupEvents, _, err := rollupClient.RollupEventsByBlock(currentBlockNum) + rollupEvents, err := rollupClient.RollupEventsByBlock(currentBlockNum, nil) require.NoError(t, err) assert.Equal(t, l1Tx.ToIdx, rollupEvents.L1UserTx[0].L1UserTx.ToIdx) assert.Equal(t, l1Tx.DepositAmount, rollupEvents.L1UserTx[0].L1UserTx.DepositAmount) @@ -659,7 +659,7 @@ func TestRollupL1UserTxETHForceTransfer(t *testing.T) { currentBlockNum, err := rollupClient.client.EthLastBlock() require.NoError(t, err) - rollupEvents, _, err := rollupClient.RollupEventsByBlock(currentBlockNum) + rollupEvents, err := rollupClient.RollupEventsByBlock(currentBlockNum, nil) require.NoError(t, err) assert.Equal(t, l1Tx.ToIdx, rollupEvents.L1UserTx[0].L1UserTx.ToIdx) assert.Equal(t, l1Tx.DepositAmount, rollupEvents.L1UserTx[0].L1UserTx.DepositAmount) @@ -688,7 +688,7 @@ func TestRollupL1UserTxERC20ForceTransfer(t *testing.T) { currentBlockNum, err := rollupClient.client.EthLastBlock() require.NoError(t, err) - rollupEvents, _, err := rollupClient.RollupEventsByBlock(currentBlockNum) + rollupEvents, err := rollupClient.RollupEventsByBlock(currentBlockNum, nil) require.NoError(t, err) assert.Equal(t, l1Tx.ToIdx, rollupEvents.L1UserTx[0].L1UserTx.ToIdx) assert.Equal(t, l1Tx.DepositAmount, rollupEvents.L1UserTx[0].L1UserTx.DepositAmount) @@ -717,7 +717,7 @@ func TestRollupL1UserTxERC20PermitForceTransfer(t *testing.T) { currentBlockNum, err := rollupClient.client.EthLastBlock() require.NoError(t, err) - rollupEvents, _, err := rollupClient.RollupEventsByBlock(currentBlockNum) + rollupEvents, err := rollupClient.RollupEventsByBlock(currentBlockNum, nil) require.NoError(t, err) assert.Equal(t, l1Tx.ToIdx, rollupEvents.L1UserTx[0].L1UserTx.ToIdx) assert.Equal(t, l1Tx.DepositAmount, rollupEvents.L1UserTx[0].L1UserTx.DepositAmount) @@ -747,7 +747,7 @@ func TestRollupL1UserTxETHForceExit(t *testing.T) { currentBlockNum, err := rollupClient.client.EthLastBlock() require.NoError(t, err) - rollupEvents, _, err := rollupClient.RollupEventsByBlock(currentBlockNum) + rollupEvents, err := rollupClient.RollupEventsByBlock(currentBlockNum, nil) require.NoError(t, err) assert.Equal(t, l1Tx.ToIdx, rollupEvents.L1UserTx[0].L1UserTx.ToIdx) assert.Equal(t, l1Tx.DepositAmount, rollupEvents.L1UserTx[0].L1UserTx.DepositAmount) @@ -776,7 +776,7 @@ func TestRollupL1UserTxERC20ForceExit(t *testing.T) { currentBlockNum, err := rollupClient.client.EthLastBlock() require.NoError(t, err) - rollupEvents, _, err := rollupClient.RollupEventsByBlock(currentBlockNum) + rollupEvents, err := rollupClient.RollupEventsByBlock(currentBlockNum, nil) require.NoError(t, err) assert.Equal(t, l1Tx.ToIdx, rollupEvents.L1UserTx[0].L1UserTx.ToIdx) assert.Equal(t, l1Tx.DepositAmount, rollupEvents.L1UserTx[0].L1UserTx.DepositAmount) @@ -807,7 +807,7 @@ func TestRollupL1UserTxERC20PermitForceExit(t *testing.T) { currentBlockNum, err := rollupClient.client.EthLastBlock() require.NoError(t, err) - rollupEvents, _, err := rollupClient.RollupEventsByBlock(currentBlockNum) + rollupEvents, err := rollupClient.RollupEventsByBlock(currentBlockNum, nil) require.NoError(t, err) assert.Equal(t, l1Tx.ToIdx, rollupEvents.L1UserTx[0].L1UserTx.ToIdx) assert.Equal(t, l1Tx.DepositAmount, rollupEvents.L1UserTx[0].L1UserTx.DepositAmount) @@ -822,7 +822,7 @@ func TestRollupForgeBatch2(t *testing.T) { require.NoError(t, err) currentBlockNum, err := rollupClient.client.EthLastBlock() require.NoError(t, err) - rollupEvents, _, err := rollupClient.RollupEventsByBlock(currentBlockNum) + rollupEvents, err := rollupClient.RollupEventsByBlock(currentBlockNum, nil) require.NoError(t, err) assert.Equal(t, int64(2), rollupEvents.ForgeBatch[0].BatchNum) @@ -876,7 +876,7 @@ func TestRollupForgeBatch2(t *testing.T) { currentBlockNum, err = rollupClient.client.EthLastBlock() require.NoError(t, err) - rollupEvents, _, err = rollupClient.RollupEventsByBlock(currentBlockNum) + rollupEvents, err = rollupClient.RollupEventsByBlock(currentBlockNum, nil) require.NoError(t, err) assert.Equal(t, int64(3), rollupEvents.ForgeBatch[0].BatchNum) @@ -928,7 +928,7 @@ func TestRollupWithdrawMerkleProof(t *testing.T) { currentBlockNum, err := rollupClient.client.EthLastBlock() require.NoError(t, err) - rollupEvents, _, err := rollupClient.RollupEventsByBlock(currentBlockNum) + rollupEvents, err := rollupClient.RollupEventsByBlock(currentBlockNum, nil) require.NoError(t, err) assert.Equal(t, uint64(fromIdx), rollupEvents.Withdraw[0].Idx) @@ -951,7 +951,7 @@ func TestRollupSafeMode(t *testing.T) { currentBlockNum, err := rollupClient.client.EthLastBlock() require.NoError(t, err) - rollupEvents, _, err := rollupClient.RollupEventsByBlock(currentBlockNum) + rollupEvents, err := rollupClient.RollupEventsByBlock(currentBlockNum, nil) require.NoError(t, err) auxEvent := new(RollupEventSafeMode) assert.Equal(t, auxEvent, &rollupEvents.SafeMode[0]) diff --git a/eth/wdelayer.go b/eth/wdelayer.go index 32e6e22..d7c3935 100644 --- a/eth/wdelayer.go +++ b/eth/wdelayer.go @@ -134,7 +134,7 @@ type WDelayerInterface interface { WDelayerWithdrawal(owner, token ethCommon.Address) (*types.Transaction, error) WDelayerEscapeHatchWithdrawal(to, token ethCommon.Address, amount *big.Int) (*types.Transaction, error) - WDelayerEventsByBlock(blockNum int64) (*WDelayerEvents, *ethCommon.Hash, error) + WDelayerEventsByBlock(blockNum int64, blockHash *ethCommon.Hash) (*WDelayerEvents, error) WDelayerConstants() (*common.WDelayerConstants, error) WDelayerEventInit() (*WDelayerEventInitialize, int64, error) } @@ -424,40 +424,47 @@ func (c *WDelayerClient) WDelayerEventInit() (*WDelayerEventInitialize, int64, e } // WDelayerEventsByBlock returns the events in a block that happened in the -// WDelayer Smart Contract and the blockHash where the eents happened. If -// there are no events in that block, blockHash is nil. -func (c *WDelayerClient) WDelayerEventsByBlock(blockNum int64) (*WDelayerEvents, *ethCommon.Hash, error) { +// WDelayer Smart Contract. +// To query by blockNum, set blockNum >= 0 and blockHash == nil. +// To query by blockHash, set blockNum == -1 and blockHash != nil. +// If there are no events in that block the result is nil. +func (c *WDelayerClient) WDelayerEventsByBlock(blockNum int64, + blockHash *ethCommon.Hash) (*WDelayerEvents, error) { var wdelayerEvents WDelayerEvents - var blockHash *ethCommon.Hash + var blockNumBigInt *big.Int + if blockNum >= 0 { + blockNumBigInt = big.NewInt(blockNum) + } query := ethereum.FilterQuery{ - FromBlock: big.NewInt(blockNum), - ToBlock: big.NewInt(blockNum), + BlockHash: blockHash, + FromBlock: blockNumBigInt, + ToBlock: blockNumBigInt, Addresses: []ethCommon.Address{ c.address, }, - BlockHash: nil, - Topics: [][]ethCommon.Hash{}, + Topics: [][]ethCommon.Hash{}, } logs, err := c.client.client.FilterLogs(context.Background(), query) if err != nil { - return nil, nil, tracerr.Wrap(err) + return nil, tracerr.Wrap(err) } - if len(logs) > 0 { - blockHash = &logs[0].BlockHash + if len(logs) == 0 { + return nil, nil } + for _, vLog := range logs { - if vLog.BlockHash != *blockHash { + if blockHash != nil && vLog.BlockHash != *blockHash { log.Errorw("Block hash mismatch", "expected", blockHash.String(), "got", vLog.BlockHash.String()) - return nil, nil, tracerr.Wrap(ErrBlockHashMismatchEvent) + return nil, tracerr.Wrap(ErrBlockHashMismatchEvent) } switch vLog.Topics[0] { case logWDelayerDeposit: var deposit WDelayerEventDeposit err := c.contractAbi.UnpackIntoInterface(&deposit, "Deposit", vLog.Data) if err != nil { - return nil, nil, tracerr.Wrap(err) + return nil, tracerr.Wrap(err) } deposit.Owner = ethCommon.BytesToAddress(vLog.Topics[1].Bytes()) deposit.Token = ethCommon.BytesToAddress(vLog.Topics[2].Bytes()) @@ -468,7 +475,7 @@ func (c *WDelayerClient) WDelayerEventsByBlock(blockNum int64) (*WDelayerEvents, var withdraw WDelayerEventWithdraw err := c.contractAbi.UnpackIntoInterface(&withdraw, "Withdraw", vLog.Data) if err != nil { - return nil, nil, tracerr.Wrap(err) + return nil, tracerr.Wrap(err) } withdraw.Token = ethCommon.BytesToAddress(vLog.Topics[1].Bytes()) withdraw.Owner = ethCommon.BytesToAddress(vLog.Topics[2].Bytes()) @@ -482,7 +489,7 @@ func (c *WDelayerClient) WDelayerEventsByBlock(blockNum int64) (*WDelayerEvents, var withdrawalDelay WDelayerEventNewWithdrawalDelay err := c.contractAbi.UnpackIntoInterface(&withdrawalDelay, "NewWithdrawalDelay", vLog.Data) if err != nil { - return nil, nil, tracerr.Wrap(err) + return nil, tracerr.Wrap(err) } wdelayerEvents.NewWithdrawalDelay = append(wdelayerEvents.NewWithdrawalDelay, withdrawalDelay) @@ -490,7 +497,7 @@ func (c *WDelayerClient) WDelayerEventsByBlock(blockNum int64) (*WDelayerEvents, var escapeHatchWithdrawal WDelayerEventEscapeHatchWithdrawal err := c.contractAbi.UnpackIntoInterface(&escapeHatchWithdrawal, "EscapeHatchWithdrawal", vLog.Data) if err != nil { - return nil, nil, tracerr.Wrap(err) + return nil, tracerr.Wrap(err) } escapeHatchWithdrawal.Who = ethCommon.BytesToAddress(vLog.Topics[1].Bytes()) escapeHatchWithdrawal.To = ethCommon.BytesToAddress(vLog.Topics[2].Bytes()) @@ -501,7 +508,7 @@ func (c *WDelayerClient) WDelayerEventsByBlock(blockNum int64) (*WDelayerEvents, var emergencyCouncil WDelayerEventNewEmergencyCouncil err := c.contractAbi.UnpackIntoInterface(&emergencyCouncil, "NewEmergencyCouncil", vLog.Data) if err != nil { - return nil, nil, tracerr.Wrap(err) + return nil, tracerr.Wrap(err) } wdelayerEvents.NewEmergencyCouncil = append(wdelayerEvents.NewEmergencyCouncil, emergencyCouncil) @@ -509,10 +516,10 @@ func (c *WDelayerClient) WDelayerEventsByBlock(blockNum int64) (*WDelayerEvents, var governanceAddress WDelayerEventNewHermezGovernanceAddress err := c.contractAbi.UnpackIntoInterface(&governanceAddress, "NewHermezGovernanceAddress", vLog.Data) if err != nil { - return nil, nil, tracerr.Wrap(err) + return nil, tracerr.Wrap(err) } wdelayerEvents.NewHermezGovernanceAddress = append(wdelayerEvents.NewHermezGovernanceAddress, governanceAddress) } } - return &wdelayerEvents, blockHash, nil + return &wdelayerEvents, nil } diff --git a/eth/wdelayer_test.go b/eth/wdelayer_test.go index 43bc0fc..c78d39d 100644 --- a/eth/wdelayer_test.go +++ b/eth/wdelayer_test.go @@ -52,7 +52,7 @@ func TestWDelayerSetHermezGovernanceAddress(t *testing.T) { assert.Equal(t, &auxAddressConst, auxAddress) currentBlockNum, err := wdelayerClientTest.client.EthLastBlock() require.Nil(t, err) - wdelayerEvents, _, err := wdelayerClientTest.WDelayerEventsByBlock(currentBlockNum) + wdelayerEvents, err := wdelayerClientTest.WDelayerEventsByBlock(currentBlockNum, nil) require.Nil(t, err) assert.Equal(t, auxAddressConst, wdelayerEvents.NewHermezGovernanceAddress[0].NewHermezGovernanceAddress) _, err = wdelayerClientAux.WDelayerTransferGovernance(governanceAddressConst) @@ -81,7 +81,7 @@ func TestWDelayerSetEmergencyCouncil(t *testing.T) { assert.Equal(t, &auxAddressConst, auxAddress) currentBlockNum, err := wdelayerClientTest.client.EthLastBlock() require.Nil(t, err) - wdelayerEvents, _, err := wdelayerClientTest.WDelayerEventsByBlock(currentBlockNum) + wdelayerEvents, err := wdelayerClientTest.WDelayerEventsByBlock(currentBlockNum, nil) require.Nil(t, err) assert.Equal(t, auxAddressConst, wdelayerEvents.NewEmergencyCouncil[0].NewEmergencyCouncil) _, err = wdelayerClientAux.WDelayerTransferEmergencyCouncil(emergencyCouncilAddressConst) @@ -110,7 +110,7 @@ func TestWDelayerChangeWithdrawalDelay(t *testing.T) { assert.Equal(t, newWithdrawalDelay, withdrawalDelay) currentBlockNum, err := wdelayerClientTest.client.EthLastBlock() require.Nil(t, err) - wdelayerEvents, _, err := wdelayerClientTest.WDelayerEventsByBlock(currentBlockNum) + wdelayerEvents, err := wdelayerClientTest.WDelayerEventsByBlock(currentBlockNum, nil) require.Nil(t, err) assert.Equal(t, uint64(newWithdrawalDelay), wdelayerEvents.NewWithdrawalDelay[0].WithdrawalDelay) } @@ -124,7 +124,7 @@ func TestWDelayerDeposit(t *testing.T) { require.Nil(t, err) currentBlockNum, err := wdelayerClientTest.client.EthLastBlock() require.Nil(t, err) - wdelayerEvents, _, err := wdelayerClientTest.WDelayerEventsByBlock(currentBlockNum) + wdelayerEvents, err := wdelayerClientTest.WDelayerEventsByBlock(currentBlockNum, nil) require.Nil(t, err) assert.Equal(t, amount, wdelayerEvents.Deposit[0].Amount) assert.Equal(t, auxAddressConst, wdelayerEvents.Deposit[0].Owner) @@ -150,7 +150,7 @@ func TestWDelayerWithdrawal(t *testing.T) { require.Nil(t, err) currentBlockNum, err := wdelayerClientTest.client.EthLastBlock() require.Nil(t, err) - wdelayerEvents, _, err := wdelayerClientTest.WDelayerEventsByBlock(currentBlockNum) + wdelayerEvents, err := wdelayerClientTest.WDelayerEventsByBlock(currentBlockNum, nil) require.Nil(t, err) assert.Equal(t, amount, wdelayerEvents.Withdraw[0].Amount) assert.Equal(t, auxAddressConst, wdelayerEvents.Withdraw[0].Owner) @@ -166,7 +166,7 @@ func TestWDelayerSecondDeposit(t *testing.T) { require.Nil(t, err) currentBlockNum, err := wdelayerClientTest.client.EthLastBlock() require.Nil(t, err) - wdelayerEvents, _, err := wdelayerClientTest.WDelayerEventsByBlock(currentBlockNum) + wdelayerEvents, err := wdelayerClientTest.WDelayerEventsByBlock(currentBlockNum, nil) require.Nil(t, err) assert.Equal(t, amount, wdelayerEvents.Deposit[0].Amount) assert.Equal(t, auxAddressConst, wdelayerEvents.Deposit[0].Owner) @@ -181,7 +181,7 @@ func TestWDelayerEnableEmergencyMode(t *testing.T) { assert.Equal(t, true, emergencyMode) currentBlockNum, err := wdelayerClientTest.client.EthLastBlock() require.Nil(t, err) - wdelayerEvents, _, err := wdelayerClientTest.WDelayerEventsByBlock(currentBlockNum) + wdelayerEvents, err := wdelayerClientTest.WDelayerEventsByBlock(currentBlockNum, nil) require.Nil(t, err) auxEvent := new(WDelayerEventEmergencyModeEnabled) assert.Equal(t, auxEvent, &wdelayerEvents.EmergencyModeEnabled[0]) @@ -210,7 +210,7 @@ func TestWDelayerEscapeHatchWithdrawal(t *testing.T) { require.Nil(t, err) currentBlockNum, err := wdelayerClientTest.client.EthLastBlock() require.Nil(t, err) - wdelayerEvents, _, err := wdelayerClientTest.WDelayerEventsByBlock(currentBlockNum) + wdelayerEvents, err := wdelayerClientTest.WDelayerEventsByBlock(currentBlockNum, nil) require.Nil(t, err) assert.Equal(t, tokenHEZAddressConst, wdelayerEvents.EscapeHatchWithdrawal[0].Token) assert.Equal(t, governanceAddressConst, wdelayerEvents.EscapeHatchWithdrawal[0].To) diff --git a/synchronizer/synchronizer.go b/synchronizer/synchronizer.go index ad03122..984b66f 100644 --- a/synchronizer/synchronizer.go +++ b/synchronizer/synchronizer.go @@ -195,15 +195,16 @@ type Config struct { // Synchronizer implements the Synchronizer type type Synchronizer struct { - ethClient eth.ClientInterface - consts SCConsts - historyDB *historydb.HistoryDB - stateDB *statedb.StateDB - cfg Config - initVars SCVariables - startBlockNum int64 - vars SCVariables - stats *StatsHolder + ethClient eth.ClientInterface + consts SCConsts + historyDB *historydb.HistoryDB + stateDB *statedb.StateDB + cfg Config + initVars SCVariables + startBlockNum int64 + vars SCVariables + stats *StatsHolder + resetStateFailed bool } // NewSynchronizer creates a new Synchronizer @@ -445,8 +446,10 @@ func (s *Synchronizer) init() error { lastBlock = lastSavedBlock } if err := s.resetState(lastBlock); err != nil { + s.resetStateFailed = true return tracerr.Wrap(err) } + s.resetStateFailed = false log.Infow("Sync init block", "syncLastBlock", s.stats.Sync.LastBlock, @@ -462,16 +465,37 @@ func (s *Synchronizer) init() error { return nil } +func (s *Synchronizer) resetIntermediateState() error { + lastBlock, err := s.historyDB.GetLastBlock() + if tracerr.Unwrap(err) == sql.ErrNoRows { + lastBlock = &common.Block{} + } else if err != nil { + return tracerr.Wrap(fmt.Errorf("historyDB.GetLastBlock: %w", err)) + } + if err := s.resetState(lastBlock); err != nil { + s.resetStateFailed = true + return tracerr.Wrap(fmt.Errorf("resetState at block %v: %w", lastBlock.Num, err)) + } + s.resetStateFailed = false + return nil +} + // Sync2 attems to synchronize an ethereum block starting from lastSavedBlock. // If lastSavedBlock is nil, the lastSavedBlock value is obtained from de DB. // If a block is synched, it will be returned and also stored in the DB. If a // reorg is detected, the number of discarded blocks will be returned and no // synchronization will be made. // TODO: Be smart about locking: only lock during the read/write operations -func (s *Synchronizer) Sync2(ctx context.Context, lastSavedBlock *common.Block) (*common.BlockData, *int64, error) { +func (s *Synchronizer) Sync2(ctx context.Context, + lastSavedBlock *common.Block) (blockData *common.BlockData, discarded *int64, err error) { + if s.resetStateFailed { + if err := s.resetIntermediateState(); err != nil { + return nil, nil, tracerr.Wrap(err) + } + } + var nextBlockNum int64 // next block number to sync if lastSavedBlock == nil { - var err error // Get lastSavedBlock from History DB lastSavedBlock, err = s.historyDB.GetLastBlock() if err != nil && tracerr.Unwrap(err) != sql.ErrNoRows { @@ -527,6 +551,20 @@ func (s *Synchronizer) Sync2(ctx context.Context, lastSavedBlock *common.Block) } } + defer func() { + // If there was an error during sync, reset to the last block + // in the historyDB because the historyDB is written last in + // the Sync method and is the source of consistency. This + // allows reseting the stateDB in the case a batch was + // processed but the historyDB block was not committed due to an + // error. + if err != nil { + if err2 := s.resetIntermediateState(); err2 != nil { + log.Errorw("sync revert", "err", err2) + } + } + }() + // Get data from the rollup contract rollupData, err := s.rollupSync(ethBlock) if err != nil { @@ -564,14 +602,14 @@ func (s *Synchronizer) Sync2(ctx context.Context, lastSavedBlock *common.Block) } // Group all the block data into the structs to save into HistoryDB - blockData := common.BlockData{ + blockData = &common.BlockData{ Block: *ethBlock, Rollup: *rollupData, Auction: *auctionData, WDelayer: *wDelayerData, } - err = s.historyDB.AddBlockSCData(&blockData) + err = s.historyDB.AddBlockSCData(blockData) if err != nil { return nil, nil, tracerr.Wrap(err) } @@ -613,7 +651,7 @@ func (s *Synchronizer) Sync2(ctx context.Context, lastSavedBlock *common.Block) ) } - return &blockData, nil, nil + return blockData, nil, nil } // reorg manages a reorg, updating History and State DB as needed. Keeps @@ -645,14 +683,15 @@ func (s *Synchronizer) reorg(uncleBlock *common.Block) (int64, error) { log.Debugw("Discarding blocks", "total", total, "from", uncleBlock.Num, "to", block.Num+1) // Set History DB and State DB to the correct state - err := s.historyDB.Reorg(block.Num) - if err != nil { + if err := s.historyDB.Reorg(block.Num); err != nil { return 0, tracerr.Wrap(err) } if err := s.resetState(block); err != nil { + s.resetStateFailed = true return 0, tracerr.Wrap(err) } + s.resetStateFailed = false return block.Num, nil } @@ -722,6 +761,11 @@ func (s *Synchronizer) resetState(block *common.Block) error { batchNum = 0 } + err = s.stateDB.Reset(batchNum) + if err != nil { + return tracerr.Wrap(fmt.Errorf("stateDB.Reset: %w", err)) + } + lastL1BatchBlockNum, err := s.historyDB.GetLastL1BatchBlockNum() if err != nil && tracerr.Unwrap(err) != sql.ErrNoRows { return tracerr.Wrap(fmt.Errorf("historyDB.GetLastL1BatchBlockNum: %w", err)) @@ -739,11 +783,6 @@ func (s *Synchronizer) resetState(block *common.Block) error { lastForgeL1TxsNum = &n } - err = s.stateDB.Reset(batchNum) - if err != nil { - return tracerr.Wrap(fmt.Errorf("stateDB.Reset: %w", err)) - } - s.stats.UpdateSync(block, &batchNum, &lastL1BatchBlockNum, lastForgeL1TxsNum) if err := s.updateCurrentNextSlotIfSync(true, nil); err != nil { @@ -761,19 +800,14 @@ func (s *Synchronizer) rollupSync(ethBlock *common.Block) (*common.RollupData, e // Get rollup events in the block, and make sure the block hash matches // the expected one. - rollupEvents, blockHash, err := s.ethClient.RollupEventsByBlock(blockNum) + rollupEvents, err := s.ethClient.RollupEventsByBlock(blockNum, ðBlock.Hash) if err != nil { return nil, tracerr.Wrap(err) } // No events in this block - if blockHash == nil { + if rollupEvents == nil { return &rollupData, nil } - if *blockHash != ethBlock.Hash { - log.Errorw("Block hash mismatch in Rollup events", "expected", ethBlock.Hash.String(), - "got", blockHash.String()) - return nil, tracerr.Wrap(eth.ErrBlockHashMismatchEvent) - } var nextForgeL1TxsNum int64 // forgeL1TxsNum for the next L1Batch nextForgeL1TxsNumPtr, err := s.historyDB.GetLastL1TxsNum() @@ -801,7 +835,7 @@ func (s *Synchronizer) rollupSync(ethBlock *common.Block) (*common.RollupData, e forgeBatchArgs, sender, err := s.ethClient.RollupForgeBatchArgs(evtForgeBatch.EthTxHash, evtForgeBatch.L1UserTxsLen) if err != nil { - return nil, tracerr.Wrap(err) + return nil, tracerr.Wrap(fmt.Errorf("RollupForgeBatchArgs: %w", err)) } batchNum := common.BatchNum(evtForgeBatch.BatchNum) @@ -884,6 +918,10 @@ func (s *Synchronizer) rollupSync(ethBlock *common.Block) (*common.RollupData, e if err != nil { return nil, tracerr.Wrap(err) } + if s.stateDB.CurrentBatch() != batchNum { + return nil, tracerr.Wrap(fmt.Errorf("stateDB.BatchNum (%v) != evtForgeBatch.BatchNum = (%v)", + s.stateDB.CurrentBatch(), batchNum)) + } // Transform processed PoolL2 txs to L2 and store in BatchData l2Txs, err := common.PoolL2TxsToL2Txs(poolL2Txs) // NOTE: This is a big uggly, find a better way @@ -1066,19 +1104,14 @@ func (s *Synchronizer) auctionSync(ethBlock *common.Block) (*common.AuctionData, var auctionData = common.NewAuctionData() // Get auction events in the block - auctionEvents, blockHash, err := s.ethClient.AuctionEventsByBlock(blockNum) + auctionEvents, err := s.ethClient.AuctionEventsByBlock(blockNum, ðBlock.Hash) if err != nil { return nil, tracerr.Wrap(err) } // No events in this block - if blockHash == nil { + if auctionEvents == nil { return &auctionData, nil } - if *blockHash != ethBlock.Hash { - log.Errorw("Block hash mismatch in Auction events", "expected", ethBlock.Hash.String(), - "got", blockHash.String()) - return nil, tracerr.Wrap(eth.ErrBlockHashMismatchEvent) - } // Get bids for _, evt := range auctionEvents.NewBid { @@ -1168,19 +1201,14 @@ func (s *Synchronizer) wdelayerSync(ethBlock *common.Block) (*common.WDelayerDat wDelayerData := common.NewWDelayerData() // Get wDelayer events in the block - wDelayerEvents, blockHash, err := s.ethClient.WDelayerEventsByBlock(blockNum) + wDelayerEvents, err := s.ethClient.WDelayerEventsByBlock(blockNum, ðBlock.Hash) if err != nil { return nil, tracerr.Wrap(err) } // No events in this block - if blockHash == nil { + if wDelayerEvents == nil { return &wDelayerData, nil } - if *blockHash != ethBlock.Hash { - log.Errorw("Block hash mismatch in WDelayer events", "expected", ethBlock.Hash.String(), - "got", blockHash.String()) - return nil, tracerr.Wrap(eth.ErrBlockHashMismatchEvent) - } for _, evt := range wDelayerEvents.Deposit { wDelayerData.Deposits = append(wDelayerData.Deposits, common.WDelayerTransfer{ diff --git a/test/ethclient.go b/test/ethclient.go index 7a5fe05..acc089b 100644 --- a/test/ethclient.go +++ b/test/ethclient.go @@ -1116,15 +1116,20 @@ func (c *Client) RollupConstants() (*common.RollupConstants, error) { } // RollupEventsByBlock returns the events in a block that happened in the Rollup Smart Contract -func (c *Client) RollupEventsByBlock(blockNum int64) (*eth.RollupEvents, *ethCommon.Hash, error) { +func (c *Client) RollupEventsByBlock(blockNum int64, + blockHash *ethCommon.Hash) (*eth.RollupEvents, error) { c.rw.RLock() defer c.rw.RUnlock() block, ok := c.blocks[blockNum] if !ok { - return nil, nil, tracerr.Wrap(fmt.Errorf("Block %v doesn't exist", blockNum)) + return nil, tracerr.Wrap(fmt.Errorf("Block %v doesn't exist", blockNum)) } - return &block.Rollup.Events, &block.Eth.Hash, nil + if blockHash != nil && *blockHash != block.Eth.Hash { + return nil, tracerr.Wrap(fmt.Errorf("Hash mismatch, requested %v got %v", + blockHash, block.Eth.Hash)) + } + return &block.Rollup.Events, nil } // RollupEventInit returns the initialize event with its corresponding block number @@ -1573,15 +1578,20 @@ func (c *Client) AuctionConstants() (*common.AuctionConstants, error) { } // AuctionEventsByBlock returns the events in a block that happened in the Auction Smart Contract -func (c *Client) AuctionEventsByBlock(blockNum int64) (*eth.AuctionEvents, *ethCommon.Hash, error) { +func (c *Client) AuctionEventsByBlock(blockNum int64, + blockHash *ethCommon.Hash) (*eth.AuctionEvents, error) { c.rw.RLock() defer c.rw.RUnlock() block, ok := c.blocks[blockNum] if !ok { - return nil, nil, tracerr.Wrap(fmt.Errorf("Block %v doesn't exist", blockNum)) + return nil, tracerr.Wrap(fmt.Errorf("Block %v doesn't exist", blockNum)) + } + if blockHash != nil && *blockHash != block.Eth.Hash { + return nil, tracerr.Wrap(fmt.Errorf("Hash mismatch, requested %v got %v", + blockHash, block.Eth.Hash)) } - return &block.Auction.Events, &block.Eth.Hash, nil + return &block.Auction.Events, nil } // AuctionEventInit returns the initialize event with its corresponding block number @@ -1789,15 +1799,20 @@ func (c *Client) WDelayerEscapeHatchWithdrawal(to, token ethCommon.Address, amou } // WDelayerEventsByBlock returns the events in a block that happened in the WDelayer Contract -func (c *Client) WDelayerEventsByBlock(blockNum int64) (*eth.WDelayerEvents, *ethCommon.Hash, error) { +func (c *Client) WDelayerEventsByBlock(blockNum int64, + blockHash *ethCommon.Hash) (*eth.WDelayerEvents, error) { c.rw.RLock() defer c.rw.RUnlock() block, ok := c.blocks[blockNum] if !ok { - return nil, nil, tracerr.Wrap(fmt.Errorf("Block %v doesn't exist", blockNum)) + return nil, tracerr.Wrap(fmt.Errorf("Block %v doesn't exist", blockNum)) + } + if blockHash != nil && *blockHash != block.Eth.Hash { + return nil, tracerr.Wrap(fmt.Errorf("Hash mismatch, requested %v got %v", + blockHash, block.Eth.Hash)) } - return &block.WDelayer.Events, &block.Eth.Hash, nil + return &block.WDelayer.Events, nil } // WDelayerConstants returns the Constants of the WDelayer Contract diff --git a/test/ethclient_test.go b/test/ethclient_test.go index e3600aa..7a7a8c9 100644 --- a/test/ethclient_test.go +++ b/test/ethclient_test.go @@ -130,7 +130,7 @@ func TestClientAuction(t *testing.T) { blockNum, err := c.EthLastBlock() require.Nil(t, err) - auctionEvents, _, err := c.AuctionEventsByBlock(blockNum) + auctionEvents, err := c.AuctionEventsByBlock(blockNum, nil) require.Nil(t, err) assert.Equal(t, 2, len(auctionEvents.NewBid)) } @@ -171,7 +171,7 @@ func TestClientRollup(t *testing.T) { blockNum, err := c.EthLastBlock() require.Nil(t, err) - rollupEvents, _, err := c.RollupEventsByBlock(blockNum) + rollupEvents, err := c.RollupEventsByBlock(blockNum, nil) require.Nil(t, err) assert.Equal(t, N, len(rollupEvents.L1UserTx)) assert.Equal(t, 1, len(rollupEvents.AddToken)) @@ -192,7 +192,7 @@ func TestClientRollup(t *testing.T) { blockNumA, err := c.EthLastBlock() require.Nil(t, err) - rollupEvents, hashA, err := c.RollupEventsByBlock(blockNumA) + rollupEvents, err = c.RollupEventsByBlock(blockNumA, nil) require.Nil(t, err) assert.Equal(t, 0, len(rollupEvents.L1UserTx)) assert.Equal(t, 0, len(rollupEvents.AddToken)) @@ -205,14 +205,14 @@ func TestClientRollup(t *testing.T) { blockNumB, err := c.EthLastBlock() require.Nil(t, err) - rollupEvents, hashB, err := c.RollupEventsByBlock(blockNumA) + rollupEventsB, err := c.RollupEventsByBlock(blockNumA, nil) require.Nil(t, err) - assert.Equal(t, 0, len(rollupEvents.L1UserTx)) - assert.Equal(t, 0, len(rollupEvents.AddToken)) - assert.Equal(t, 0, len(rollupEvents.ForgeBatch)) + assert.Equal(t, 0, len(rollupEventsB.L1UserTx)) + assert.Equal(t, 0, len(rollupEventsB.AddToken)) + assert.Equal(t, 0, len(rollupEventsB.ForgeBatch)) assert.Equal(t, blockNumA, blockNumB) - assert.NotEqual(t, hashA, hashB) + assert.NotEqual(t, rollupEvents, rollupEventsB) // Forge again rollupForgeBatchArgs0 := ð.RollupForgeBatchArgs{ @@ -232,7 +232,7 @@ func TestClientRollup(t *testing.T) { blockNum, err = c.EthLastBlock() require.Nil(t, err) - rollupEvents, _, err = c.RollupEventsByBlock(blockNum) + rollupEvents, err = c.RollupEventsByBlock(blockNum, nil) require.Nil(t, err) rollupForgeBatchArgs1, sender, err := c.RollupForgeBatchArgs(rollupEvents.ForgeBatch[0].EthTxHash,