diff --git a/turbo/jsonrpc/zkevm_api.go b/turbo/jsonrpc/zkevm_api.go index 7523214d8b4..dada5250041 100644 --- a/turbo/jsonrpc/zkevm_api.go +++ b/turbo/jsonrpc/zkevm_api.go @@ -733,12 +733,12 @@ func (api *ZkEvmAPIImpl) getAccInputHash(ctx context.Context, db SequenceReader, return nil, fmt.Errorf("failed to get old acc input hash for batch %d: %w", prevSequenceBatch, err) } - decodedSequenceInteerface, err := syncer.DecodeSequenceBatchesCalldata(sequenceBatchesCalldata) + decodedSequenceInterface, err := syncer.DecodeSequenceBatchesCalldata(sequenceBatchesCalldata) if err != nil { return nil, fmt.Errorf("failed to decode calldata for tx %s: %w", batchSequence.L1TxHash, err) } - accInputHashCalcFn, totalSequenceBatches, err := syncer.GetAccInputDataCalcFunction(batchSequence.L1InfoRoot, decodedSequenceInteerface) + accInputHashCalcFn, totalSequenceBatches, err := syncer.GetAccInputDataCalcFunction(batchSequence.L1InfoRoot, decodedSequenceInterface) if err != nil { return nil, fmt.Errorf("failed to get accInputHash calculation func: %w", err) } diff --git a/zk/syncer/utils.go b/zk/syncer/utils.go index 203405ad2a1..a6ad885af74 100644 --- a/zk/syncer/utils.go +++ b/zk/syncer/utils.go @@ -16,8 +16,8 @@ const ( sequenceBatchesValidiumMethodName = "sequenceBatchesValidium" ) -func GetAccInputDataCalcFunction(l1InfoRoot common.Hash, decodedSequenceInteerface interface{}) (accInputHashCalcFn func(prevAccInputHash common.Hash, index int) *common.Hash, totalSequenceBatches int, err error) { - switch decodedSequence := decodedSequenceInteerface.(type) { +func GetAccInputDataCalcFunction(l1InfoRoot common.Hash, decodedSequenceInterface interface{}) (accInputHashCalcFn func(prevAccInputHash common.Hash, index int) *common.Hash, totalSequenceBatches int, err error) { + switch decodedSequence := decodedSequenceInterface.(type) { case *SequenceBatchesCalldataPreEtrog: accInputHashCalcFn = func(prevAccInputHash common.Hash, index int) *common.Hash { return utils.CalculatePreEtrogAccInputHash(prevAccInputHash, decodedSequence.Batches[index].Transactions, decodedSequence.Batches[index].GlobalExitRoot, decodedSequence.Batches[index].Timestamp, decodedSequence.L2Coinbase) @@ -33,6 +33,11 @@ func GetAccInputDataCalcFunction(l1InfoRoot common.Hash, decodedSequenceInteerfa return utils.CalculateEtrogAccInputHash(prevAccInputHash, decodedSequence.Batches[index].Transactions, l1InfoRoot, decodedSequence.MaxSequenceTimestamp, decodedSequence.L2Coinbase, decodedSequence.Batches[index].ForcedBlockHashL1) } totalSequenceBatches = len(decodedSequence.Batches) + case *SequenceBatchesCalldataBanana: + accInputHashCalcFn = func(prevAccInputHash common.Hash, index int) *common.Hash { + return utils.CalculateBananaAccInputHash(prevAccInputHash, decodedSequence.Batches[index].Transactions, l1InfoRoot, decodedSequence.MaxSequenceTimestamp, decodedSequence.L2Coinbase, decodedSequence.Batches[index].ForcedBlockHashL1) + } + totalSequenceBatches = len(decodedSequence.Batches) case *SequenceBatchesCalldataValidiumPreEtrog: accInputHashCalcFn = func(prevAccInputHash common.Hash, index int) *common.Hash { return utils.CalculatePreEtrogValidiumAccInputHash(prevAccInputHash, decodedSequence.Batches[index].TransactionsHash, decodedSequence.Batches[index].GlobalExitRoot, decodedSequence.Batches[index].Timestamp, decodedSequence.L2Coinbase) @@ -48,8 +53,13 @@ func GetAccInputDataCalcFunction(l1InfoRoot common.Hash, decodedSequenceInteerfa return utils.CalculateEtrogValidiumAccInputHash(prevAccInputHash, decodedSequence.Batches[index].TransactionsHash, l1InfoRoot, decodedSequence.MaxSequenceTimestamp, decodedSequence.L2Coinbase, decodedSequence.Batches[index].ForcedBlockHashL1) } totalSequenceBatches = len(decodedSequence.Batches) + case *SequenceBatchesCalldataValidiumBanana: + accInputHashCalcFn = func(prevAccInputHash common.Hash, index int) *common.Hash { + return utils.CalculateBananaValidiumAccInputHash(prevAccInputHash, decodedSequence.Batches[index].TransactionHash, l1InfoRoot, decodedSequence.MaxSequenceTimestamp, decodedSequence.L2Coinbase, decodedSequence.Batches[index].ForcedBlockHashL1) + } + totalSequenceBatches = len(decodedSequence.Batches) default: - return nil, 0, fmt.Errorf("unexpected type of decoded sequence calldata: %T", decodedSequenceInteerface) + return nil, 0, fmt.Errorf("unexpected type of decoded sequence calldata: %T", decodedSequenceInterface) } return accInputHashCalcFn, totalSequenceBatches, nil @@ -101,11 +111,95 @@ func DecodeSequenceBatchesCalldata(data []byte) (calldata interface{}, err error } else { return decodeElderberryBatchesValidiumCallData(unpackedCalldata), nil } + case contracts.SequenceBatchesBanana: + if method.Name == sequenceBatchesMethodName { + return decodeBananaSequenceBatchesCallData(unpackedCalldata), nil + } else { + return decodeBananaSequenceBatchesValidiumCallData(unpackedCalldata), nil + } default: return nil, fmt.Errorf("no decoder found for method signature: %s", methodSig) } } +type SequencedBatchBanana struct { + Transactions []byte + ForcedGlobalExitRoot common.Hash + ForcedTimestamp uint64 + ForcedBlockHashL1 common.Hash +} + +type SequenceBatchesCalldataBanana struct { + Batches []SequencedBatchBanana + L2Coinbase common.Address + MaxSequenceTimestamp uint64 +} + +func decodeBananaSequenceBatchesCallData(unpackedCalldata map[string]interface{}) *SequenceBatchesCalldataBanana { + unpackedbatches := unpackedCalldata["batches"].([]struct { + Transactions []uint8 `json:"transactions"` + ForcedGlobalExitRoot [32]uint8 `json:"forcedGlobalExitRoot"` + ForcedTimestamp uint64 `json:"forcedTimestamp"` + ForcedBlockHashL1 [32]uint8 `json:"forcedBlockHashL1"` + }) + + calldata := &SequenceBatchesCalldataBanana{ + Batches: make([]SequencedBatchBanana, len(unpackedbatches)), + L2Coinbase: unpackedCalldata["l2Coinbase"].(common.Address), + MaxSequenceTimestamp: unpackedCalldata["maxSequenceTimestamp"].(uint64), + } + + for i, batch := range unpackedbatches { + calldata.Batches[i] = SequencedBatchBanana{ + Transactions: batch.Transactions, + ForcedGlobalExitRoot: common.BytesToHash(batch.ForcedGlobalExitRoot[:]), + ForcedTimestamp: batch.ForcedTimestamp, + ForcedBlockHashL1: common.BytesToHash(batch.ForcedBlockHashL1[:]), + } + } + + return calldata +} + +type SequencedBatchValidiumBanana struct { + TransactionHash common.Hash + ForcedGlobalExitRoot common.Hash + ForcedTimestamp uint64 + ForcedBlockHashL1 common.Hash +} + +type SequenceBatchesCalldataValidiumBanana struct { + Batches []SequencedBatchValidiumBanana + L2Coinbase common.Address + MaxSequenceTimestamp uint64 +} + +func decodeBananaSequenceBatchesValidiumCallData(unpackedCalldata map[string]interface{}) *SequenceBatchesCalldataValidiumBanana { + unpackedbatches := unpackedCalldata["batches"].([]struct { + TransactionHash [32]uint8 `json:"transactionHash"` + ForcedGlobalExitRoot [32]uint8 `json:"forcedGlobalExitRoot"` + ForcedTimestamp uint64 `json:"forcedTimestamp"` + ForcedBlockHashL1 [32]uint8 `json:"forcedBlockHashL1"` + }) + + calldata := &SequenceBatchesCalldataValidiumBanana{ + Batches: make([]SequencedBatchValidiumBanana, len(unpackedbatches)), + L2Coinbase: unpackedCalldata["l2Coinbase"].(common.Address), + MaxSequenceTimestamp: unpackedCalldata["maxSequenceTimestamp"].(uint64), + } + + for i, batch := range unpackedbatches { + calldata.Batches[i] = SequencedBatchValidiumBanana{ + TransactionHash: common.BytesToHash(batch.TransactionHash[:]), + ForcedGlobalExitRoot: common.BytesToHash(batch.ForcedGlobalExitRoot[:]), + ForcedTimestamp: batch.ForcedTimestamp, + ForcedBlockHashL1: common.BytesToHash(batch.ForcedBlockHashL1[:]), + } + } + + return calldata +} + type SequencedBatchElderberry struct { Transactions []byte ForcedGlobalExitRoot common.Hash diff --git a/zk/utils/acc_input_hash.go b/zk/utils/acc_input_hash.go index 2a987015cdb..7a66b899ee9 100644 --- a/zk/utils/acc_input_hash.go +++ b/zk/utils/acc_input_hash.go @@ -8,6 +8,40 @@ import ( "github.com/ledgerwatch/erigon/crypto" ) +func CalculateBananaAccInputHash( + oldAccInputHash common.Hash, + batchTransactionData []byte, + l1InfoRoot common.Hash, + limitTimestamp uint64, + sequencerAddress common.Address, + forcedBlockHashL1 common.Hash, +) *common.Hash { + return CalculateEtrogAccInputHash( + oldAccInputHash, + batchTransactionData, + l1InfoRoot, + limitTimestamp, + sequencerAddress, + forcedBlockHashL1) +} + +func CalculateBananaValidiumAccInputHash( + oldAccInputHash common.Hash, + batchTransactionData common.Hash, + l1InfoRoot common.Hash, + limitTimestamp uint64, + sequencerAddress common.Address, + forcedBlockHashL1 common.Hash, +) *common.Hash { + return CalculateEtrogValidiumAccInputHash( + oldAccInputHash, + batchTransactionData, + l1InfoRoot, + limitTimestamp, + sequencerAddress, + forcedBlockHashL1) +} + // calculates the new accInputHash based on the old one and data frem one new batch // this returns the accInputHash for the current batch // oldAccInputHash - the accInputHash from the previous batch