Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Offset batch number for espresso sequencer #76

Merged
merged 2 commits into from
Sep 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion etherman/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,6 @@ type Config struct {
MultiGasProvider bool `mapstructure:"MultiGasProvider"`
Etherscan etherscan.Config

HotShotQueryServiceURL string `mapstructure:"HotShotQueryServiceURL"`
HotShotQueryServiceURL string `mapstructure:"HotShotQueryServiceURL"`
GenesisHotShotBlockNumber uint64 `mapstructure:"GenesisHotShotBlockNumber"`
}
54 changes: 39 additions & 15 deletions etherman/etherman.go
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,9 @@ func NewClient(cfg Config) (*Client, error) {
gProviders = append(gProviders, ethgasstation.NewEthGasStationService())
}

log.Infof("Hotshot address %s", cfg.HotShotAddr.String())
log.Infof("Genesis hotshot block number %d", cfg.GenesisHotShotBlockNumber)

return &Client{
EthClient: ethClient,
PoE: poe,
Expand Down Expand Up @@ -504,7 +507,7 @@ func (etherMan *Client) GetPreconfirmations(ctx context.Context, fromL2Block uin
var blocks []Block
order := make(map[common.Hash][]Order)

log.Info("Getting L2 blocks in range ", fromL2Block, "-", l2BlockHeight)
log.Infof("Getting L2 blocks in range ", fromL2Block, "-", l2BlockHeight)
for l2BlockNum := fromL2Block; l2BlockNum < l2BlockHeight; l2BlockNum++ {
var batch SequencedBatch
var l1BlockNum uint64
Expand All @@ -523,11 +526,12 @@ func (etherMan *Client) GetPreconfirmations(ctx context.Context, fromL2Block uin
}

func (etherMan *Client) newBlocksEvent(ctx context.Context, vLog types.Log, blocks *[]Block, blocksOrder *map[common.Hash][]Order) error {
log.Debug("NewBlocks event detected")
newBlocks, err := etherMan.HotShot.ParseNewBlocks(vLog)
if err != nil {
return err
}
log.Debug("NewBlocks event detected %+v", newBlocks)

// Read the tx for this event.
tx, isPending, err := etherMan.EthClient.TransactionByHash(ctx, vLog.TxHash)
if err != nil {
Expand Down Expand Up @@ -595,31 +599,42 @@ func (etherMan *Client) decodeSequencesHotShot(ctx context.Context, txData []byt

// Get number of batches by parsing transaction
numNewBatches := newBlocks.NumBlocks.Uint64()
firstNewBatchNum := newBlocks.FirstBlockNumber.Uint64()
firstHotShotBlockNum := newBlocks.FirstBlockNumber.Uint64()

sequencedBatches := make([]SequencedBatch, numNewBatches)
var sequencedBatches []SequencedBatch
for i := uint64(0); i < numNewBatches; i++ {
curBatchNum := firstNewBatchNum + i
err := etherMan.fetchL2Block(ctx, curBatchNum, &sequencedBatches[i], nil)
curHotShotBlockNum := firstHotShotBlockNum + i

if curHotShotBlockNum <= etherMan.cfg.GenesisHotShotBlockNumber {
log.Infof(
"Hotshot block number %d not greater than genesis block number %d: skipping",
curHotShotBlockNum,
etherMan.cfg.GenesisHotShotBlockNumber,
)
continue
}
newBatch := SequencedBatch{}
err := etherMan.fetchL2Block(ctx, curHotShotBlockNum, &newBatch, nil)
if err != nil {
return nil, err
}
sequencedBatches = append(sequencedBatches, newBatch)
}

return sequencedBatches, nil
}

func (etherMan *Client) fetchL2Block(ctx context.Context, l2BlockNum uint64, batch *SequencedBatch, l1BlockNum *uint64) error {
func (etherMan *Client) fetchL2Block(ctx context.Context, hotShotBlockNum uint64, batch *SequencedBatch, l1BlockNum *uint64) error {
// Get transactions and metadata from HotShot query service
l2BlockNumStr := strconv.FormatUint(l2BlockNum, 10)
hotShotBlockNumStr := strconv.FormatUint(hotShotBlockNum, 10)

// Retry until we get a response from the query service
//
// Very recent blocks may not available on the query service. If we return
// an error immediately all the batches need to be re-processed and the
// error will likely occur again. If instead we retry a few times here we
// can successfully fetch all the L2 blocks.
url := etherMan.cfg.HotShotQueryServiceURL + "/availability/block/" + l2BlockNumStr
url := etherMan.cfg.HotShotQueryServiceURL + "/availability/block/" + hotShotBlockNumStr
maxRetries := 10
var response *http.Response
var err error
Expand All @@ -639,9 +654,9 @@ func (etherMan *Client) fetchL2Block(ctx context.Context, l2BlockNum uint64, bat
}

if err != nil {
log.Warnf("Error fetching batch %d from query service, try %d: %v", l2BlockNum, i+1, err)
log.Warnf("Error fetching l2 block %d from query service, try %d: %v", hotShotBlockNum, i+1, err)
} else {
log.Warnf("Error fetching batch %d from query service, try %d: status code %d", l2BlockNum, i+1, response.StatusCode)
log.Warnf("Error fetching l2 block %d from query service, try %d: status code %d", hotShotBlockNum, i+1, response.StatusCode)
}

if i < maxRetries-1 {
Expand All @@ -651,7 +666,7 @@ func (etherMan *Client) fetchL2Block(ctx context.Context, l2BlockNum uint64, bat

// Handle the case if retries exhausted and still not successful
if response == nil || response.StatusCode != 200 {
return fmt.Errorf("Failed to fetch batch %d from query service after %d attempts", l2BlockNum, maxRetries)
return fmt.Errorf("Failed to fetch l2 block %d from query service after %d attempts", hotShotBlockNum, maxRetries)
}

var l2Block SequencerBlock
Expand All @@ -661,7 +676,13 @@ func (etherMan *Client) fetchL2Block(ctx context.Context, l2BlockNum uint64, bat
panic(err)
}

log.Info("Fetched batch ", l2BlockNum, ": L1 block %v, timestamp %v, transactions ", l2Block.L1Block, l2Block.Timestamp, l2Block.Transactions)
log.Infof(
"Fetched L1 block %d, hotshot block: %d, timestamp %v, transactions %v",
l2Block.L1Block,
l2Block.Height,
l2Block.Timestamp,
l2Block.Transactions,
)
txns, err := hex.DecodeHex(l2Block.Transactions)
if err != nil {
// It's unlikely we can recover from this error by retrying.
Expand All @@ -685,7 +706,7 @@ func (etherMan *Client) fetchL2Block(ctx context.Context, l2BlockNum uint64, bat
// should not contain any transactions for this L2, since they were created before the L2
// was deployed. In this case it doesn't matter what global exit root we use.
if len(txns) != 0 {
return fmt.Errorf("block %v (L1 block %v) contains L2 transactions from before GlobalExitRootManager was deployed", l2BlockNum, l1Block.Number())
return fmt.Errorf("block %v (L1 block %v) contains L2 transactions from before GlobalExitRootManager was deployed", hotShotBlockNum, l1Block.Number())
}
} else {
ger, err = etherMan.GlobalExitRootManager.GetLastGlobalExitRoot(&bind.CallOpts{BlockNumber: l1Block.Number()})
Expand All @@ -700,8 +721,11 @@ func (etherMan *Client) fetchL2Block(ctx context.Context, l2BlockNum uint64, bat
Timestamp: l2Block.Timestamp,
}

batchNum := hotShotBlockNum - etherMan.cfg.GenesisHotShotBlockNumber
log.Infof("Creating batch number %d", batchNum)

*batch = SequencedBatch{
BatchNumber: l2BlockNum + 1,
BatchNumber: batchNum,
PolygonZkEVMBatchData: newBatchData, // BatchData info

// Some metadata (in particular: information about the L1 transaction which sequenced this
Expand Down
4 changes: 2 additions & 2 deletions synchronizer/synchronizer.go
Original file line number Diff line number Diff line change
Expand Up @@ -211,8 +211,8 @@ func (s *ClientSynchronizer) syncBlocks(lastEthBlockSynced *state.Block) (*state

for {
toBlock := fromBlock + s.cfg.SyncChunkSize
log.Infof("Syncing block %d of %d", fromBlock, lastKnownBlock.Uint64())
log.Infof("Getting rollup info from block %d to block %d", fromBlock, toBlock)
log.Infof("Syncing L1 block %d of %d", fromBlock, lastKnownBlock.Uint64())
log.Infof("Getting rollup info from L1 block %d to block %d", fromBlock, toBlock)
// This function returns the rollup information contained in the ethereum blocks and an extra param called order.
// Order param is a map that contains the event order to allow the synchronizer store the info in the same order that is readed.
// Name can be defferent in the order struct. For instance: Batches or Name:NewSequencers. This name is an identifier to check
Expand Down
1 change: 1 addition & 0 deletions test/config/test.node.config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ HotShotAddr = "0x0000000000000000000000000000000000000000"
HotShotQueryServiceURL = "NOT_SET"
L1ChainID = 1337
MultiGasProvider = false
GenesisHotShotBlockNumber = 1
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think setting a default might not actually make much sense.

[Etherscan]
ApiKey = ""

Expand Down