From 28f660fd1d05d503b9da1e16e4eb3e1a9d01b77a Mon Sep 17 00:00:00 2001 From: David Date: Fri, 29 Sep 2023 14:36:02 +0800 Subject: [PATCH] feat: update `encoding` package --- .github/workflows/test.yml | 1 + bindings/encoding/input.go | 219 ++++--------------------------- bindings/encoding/input_test.go | 136 +------------------ bindings/encoding/struct.go | 37 +++--- bindings/encoding/struct_test.go | 21 --- 5 files changed, 45 insertions(+), 369 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index b8dde3246..9e6063d86 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -45,6 +45,7 @@ jobs: with: repository: taikoxyz/taiko-mono path: ${{ env.TAIKO_MONO_DIR }} + ref: contestable-zkrollup - name: Install Foundry uses: foundry-rs/foundry-toolchain@v1 diff --git a/bindings/encoding/input.go b/bindings/encoding/input.go index 12ec44ebb..65da78de7 100644 --- a/bindings/encoding/input.go +++ b/bindings/encoding/input.go @@ -1,103 +1,16 @@ package encoding import ( - "bytes" "errors" "fmt" "github.com/ethereum/go-ethereum/accounts/abi" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/rlp" "github.com/taikoxyz/taiko-client/bindings" ) // ABI arguments marshaling components. var ( - blockMetadataInputComponents = []abi.ArgumentMarshaling{ - { - Name: "txListHash", - Type: "bytes32", - }, - { - Name: "proposer", - Type: "address", - }, - { - Name: "txListByteStart", - Type: "uint24", - }, - { - Name: "txListByteEnd", - Type: "uint24", - }, - { - Name: "cacheTxListInfo", - Type: "bool", - }, - } - blockMetadataComponents = []abi.ArgumentMarshaling{ - { - Name: "id", - Type: "uint64", - }, - { - Name: "timestamp", - Type: "uint64", - }, - { - Name: "l1Height", - Type: "uint64", - }, - { - Name: "l1Hash", - Type: "bytes32", - }, - { - Name: "mixHash", - Type: "bytes32", - }, - { - Name: "txListHash", - Type: "bytes32", - }, - { - Name: "txListByteStart", - Type: "uint24", - }, - { - Name: "txListByteEnd", - Type: "uint24", - }, - { - Name: "gasLimit", - Type: "uint32", - }, - { - Name: "proposer", - Type: "address", - }, - { - Name: "depositsProcessed", - Type: "tuple[]", - Components: []abi.ArgumentMarshaling{ - { - Name: "recipient", - Type: "address", - }, - { - Name: "amount", - Type: "uint96", - }, - { - Name: "id", - Type: "uint64", - }, - }, - }, - } evidenceComponents = []abi.ArgumentMarshaling{ { Name: "metaHash", @@ -120,11 +33,11 @@ var ( Type: "bytes32", }, { - Name: "prover", - Type: "address", + Name: "tier", + Type: "uint16", }, { - Name: "proofs", + Name: "proof", Type: "bytes", }, } @@ -134,48 +47,41 @@ var ( Type: "address", }, { - Name: "expiry", - Type: "uint64", - }, - { - Name: "data", - Type: "bytes", - }, - } - proposeBlockDataComponents = []abi.ArgumentMarshaling{ - { - Name: "input", - Type: "tuple", - Components: blockMetadataInputComponents, + Name: "feeToken", + Type: "address", }, { - Name: "fee", - Type: "uint256", + Name: "tierFees", + Type: "tuple[]", + Components: []abi.ArgumentMarshaling{ + { + Name: "tier", + Type: "uint64", + }, + { + Name: "fee", + Type: "uint256", + }, + }, }, - { Name: "expiry", Type: "uint64", }, + { + Name: "signature", + Type: "bytes", + }, } ) var ( - // BlockMetadataInput - blockMetadataInputType, _ = abi.NewType("tuple", "TaikoData.BlockMetadataInput", blockMetadataInputComponents) - blockMetadataInputArgs = abi.Arguments{{Name: "BlockMetadataInput", Type: blockMetadataInputType}} - // BlockMetadata - blockMetadataType, _ = abi.NewType("tuple", "TaikoData.BlockMetadata", blockMetadataComponents) - blockMetadataArgs = abi.Arguments{{Name: "BlockMetadata", Type: blockMetadataType}} // Evidence EvidenceType, _ = abi.NewType("tuple", "TaikoData.BlockEvidence", evidenceComponents) EvidenceArgs = abi.Arguments{{Name: "Evidence", Type: EvidenceType}} // ProverAssignment proverAssignmentType, _ = abi.NewType("tuple", "ProverAssignment", proverAssignmentComponents) proverAssignmentArgs = abi.Arguments{{Name: "ProverAssignment", Type: proverAssignmentType}} - // ProposeBlockData - proposeBlockDataType, _ = abi.NewType("tuple", "ProposeBlockData", proposeBlockDataComponents) - proposeBlockDataArgs = abi.Arguments{{Name: "ProposeBlockData", Type: proposeBlockDataType}} ) // Contract ABIs. @@ -196,24 +102,6 @@ func init() { } } -// EncodeBlockMetadataInput performs the solidity `abi.encode` for the given blockMetadataInput. -func EncodeBlockMetadataInput(meta *TaikoL1BlockMetadataInput) ([]byte, error) { - b, err := blockMetadataInputArgs.Pack(meta) - if err != nil { - return nil, fmt.Errorf("failed to abi.encode block metadata input, %w", err) - } - return b, nil -} - -// EncodeBlockMetadata performs the solidity `abi.encode` for the given blockMetadata. -func EncodeBlockMetadata(meta *bindings.TaikoDataBlockMetadata) ([]byte, error) { - b, err := blockMetadataArgs.Pack(meta) - if err != nil { - return nil, fmt.Errorf("failed to abi.encode block metadata, %w", err) - } - return b, nil -} - // EncodeProverAssignment performs the solidity `abi.encode` for the given proverAssignment. func EncodeProverAssignment(assignment *ProverAssignment) ([]byte, error) { b, err := proverAssignmentArgs.Pack(assignment) @@ -223,17 +111,8 @@ func EncodeProverAssignment(assignment *ProverAssignment) ([]byte, error) { return b, nil } -// EncodeProposeBlockData performs the solidity `abi.encode` for the given proposeBlockData. -func EncodeProposeBlockData(data *ProposeBlockData) ([]byte, error) { - b, err := proposeBlockDataArgs.Pack(data) - if err != nil { - return nil, fmt.Errorf("failed to abi.encode proposeBlock data, %w", err) - } - return b, nil -} - // EncodeEvidence performs the solidity `abi.encode` for the given evidence. -func EncodeEvidence(e *TaikoL1Evidence) ([]byte, error) { +func EncodeEvidence(e *BlockEvidence) ([]byte, error) { b, err := EvidenceArgs.Pack(e) if err != nil { return nil, fmt.Errorf("failed to abi.encode evidence, %w", err) @@ -241,60 +120,6 @@ func EncodeEvidence(e *TaikoL1Evidence) ([]byte, error) { return b, nil } -// EncodeCommitHash performs the solidity `abi.encodePacked` for the given -// commitHash components. -func EncodeCommitHash(beneficiary common.Address, txListHash [32]byte) []byte { - // keccak256(abi.encodePacked(beneficiary, txListHash)); - return crypto.Keccak256( - bytes.Join([][]byte{beneficiary.Bytes(), txListHash[:]}, nil), - ) -} - -// EncodeProposeBlockInput encodes the input params for TaikoL1.proposeBlock. -func EncodeProposeBlockInput(metadataInput *TaikoL1BlockMetadataInput) ([]byte, error) { - metaBytes, err := EncodeBlockMetadataInput(metadataInput) - if err != nil { - return nil, err - } - return metaBytes, nil -} - -// EncodeProveBlockInput encodes the input params for TaikoL1.proveBlock. -func EncodeProveBlockInput( - evidence *TaikoL1Evidence, -) ([]byte, error) { - evidenceBytes, err := EncodeEvidence(evidence) - if err != nil { - return nil, err - } - - return evidenceBytes, nil -} - -// EncodeProveBlockInvalidInput encodes the input params for TaikoL1.proveBlockInvalid. -func EncodeProveBlockInvalidInput( - evidence *TaikoL1Evidence, - target *bindings.TaikoDataBlockMetadata, - receipt *types.Receipt, -) ([][]byte, error) { - evidenceBytes, err := EncodeEvidence(evidence) - if err != nil { - return nil, err - } - - metaBytes, err := EncodeBlockMetadata(target) - if err != nil { - return nil, err - } - - receiptBytes, err := rlp.EncodeToBytes(receipt) - if err != nil { - return nil, err - } - - return [][]byte{evidenceBytes, metaBytes, receiptBytes}, nil -} - // UnpackTxListBytes unpacks the input data of a TaikoL1.proposeBlock transaction, and returns the txList bytes. func UnpackTxListBytes(txData []byte) ([]byte, error) { method, err := TaikoL1ABI.MethodById(txData) diff --git a/bindings/encoding/input_test.go b/bindings/encoding/input_test.go index 7b17cf93e..d031ffb6e 100644 --- a/bindings/encoding/input_test.go +++ b/bindings/encoding/input_test.go @@ -7,19 +7,17 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/ethereum/go-ethereum/core/types" "github.com/stretchr/testify/require" - "github.com/taikoxyz/taiko-client/bindings" ) func TestEncodeEvidence(t *testing.T) { - evidence := &TaikoL1Evidence{ + evidence := &BlockEvidence{ MetaHash: randomHash(), BlockHash: randomHash(), ParentHash: randomHash(), SignalRoot: randomHash(), Graffiti: randomHash(), - Prover: common.BigToAddress(new(big.Int).SetUint64(rand.Uint64())), + Tier: uint16(rand.Uint64()), Proofs: randomHash().Big().Bytes(), } @@ -29,40 +27,14 @@ func TestEncodeEvidence(t *testing.T) { require.NotEmpty(t, b) } -func TestEncodeCommitHash(t *testing.T) { - require.NotEmpty(t, EncodeCommitHash(common.BytesToAddress(randomHash().Bytes()), randomHash())) -} - -func TestEncodeProposeBlockInput(t *testing.T) { - encoded, err := EncodeProposeBlockInput(&testMetaInput) - - require.Nil(t, err) - require.NotNil(t, encoded) -} - -func TestEncodeProveBlockInput(t *testing.T) { - encoded, err := EncodeProveBlockInput( - &TaikoL1Evidence{ - MetaHash: randomHash(), - BlockHash: randomHash(), - ParentHash: randomHash(), - SignalRoot: randomHash(), - Graffiti: randomHash(), - Prover: common.BigToAddress(new(big.Int).SetUint64(rand.Uint64())), - Proofs: randomHash().Big().Bytes(), - }, - ) - - require.Nil(t, err) - require.NotNil(t, encoded) -} - func TestEncodeProverAssignment(t *testing.T) { encoded, err := EncodeProverAssignment( &ProverAssignment{ - Prover: common.BigToAddress(new(big.Int).SetUint64(rand.Uint64())), - Data: randomHash().Big().Bytes(), - Expiry: 1024, + Prover: common.BigToAddress(new(big.Int).SetUint64(rand.Uint64())), + FeeToken: common.Address{}, + TierFees: []*TierFee{}, + Signature: randomHash().Big().Bytes(), + Expiry: 1024, }, ) @@ -70,100 +42,6 @@ func TestEncodeProverAssignment(t *testing.T) { require.NotNil(t, encoded) } -func TestEncodeProveBlockInvalidInput(t *testing.T) { - encoded, err := EncodeProveBlockInvalidInput( - &TaikoL1Evidence{ - MetaHash: randomHash(), - BlockHash: randomHash(), - ParentHash: randomHash(), - SignalRoot: randomHash(), - Graffiti: randomHash(), - Prover: common.BigToAddress(new(big.Int).SetUint64(rand.Uint64())), - Proofs: randomHash().Big().Bytes(), - }, - &testMeta, - types.NewReceipt(randomHash().Bytes(), false, 1024), - ) - - require.Nil(t, err) - require.NotNil(t, encoded) -} - -func TestEncodeBlockMetadata(t *testing.T) { - // since strings are right padded in solidity https://github.com/ethereum/solidity/issues/1340 - var abcdBytes [32]byte - copy(abcdBytes[:], common.RightPadBytes([]byte("abcd"), 32)) - - // Encode block metadata using EncodeBlockMetadata function - encoded, err := EncodeBlockMetadata(&bindings.TaikoDataBlockMetadata{ - Id: uint64(1), - L1Height: uint64(1), - L1Hash: abcdBytes, - Proposer: common.HexToAddress("0x10020FCb72e27650651B05eD2CEcA493bC807Ba4"), - TxListHash: abcdBytes, - TxListByteStart: big.NewInt(0), - TxListByteEnd: big.NewInt(1000), - GasLimit: 1, - MixHash: abcdBytes, - Timestamp: uint64(1), - DepositsProcessed: []bindings.TaikoDataEthDeposit{}, - }) - - require.Nil(t, err) - require.NotNil(t, encoded) - - kgv, err := hexutil.Decode("0x00000000000000000000000000000000000000000000000000000000" + - "0000002000000000000000000000000000000000000000000000000000000000000000010000000000000" + - "0000000000000000000000000000000000000000000000000010000000000000000000000000000000000" + - "0000000000000000000000000000016162636400000000000000000000000000000000000000000000000" + - "0000000006162636400000000000000000000000000000000000000000000000000000000616263640000" + - "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + - "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + - "00000003e8000000000000000000000000000000000000000000000000000000000000000100000000000" + - "000000000000010020fcb72e27650651b05ed2ceca493bc807ba400000000000000000000000000000000" + - "0000000000000000000000000000016000000000000000000000000000000000000000000000000000000" + - "00000000000") - - require.Nil(t, err) - require.Equal(t, kgv, encoded) - - encoded2, err := EncodeBlockMetadata(&bindings.TaikoDataBlockMetadata{ - Id: uint64(1), - L1Height: uint64(1), - L1Hash: abcdBytes, - Proposer: common.HexToAddress("0x10020FCb72e27650651B05eD2CEcA493bC807Ba4"), - TxListHash: abcdBytes, - TxListByteStart: big.NewInt(0), - TxListByteEnd: big.NewInt(1000), - GasLimit: 1, - MixHash: abcdBytes, - Timestamp: uint64(1), - DepositsProcessed: []bindings.TaikoDataEthDeposit{ - {Recipient: common.HexToAddress("0x10020FCb72e27650651B05eD2CEcA493bC807Ba4"), Amount: big.NewInt(2), Id: uint64(1)}, - }, - }) - - require.Nil(t, err) - require.NotNil(t, encoded2) - - kgv2, err := hexutil.Decode("0x0000000000000000000000000000000000000000000000000000000" + - "0000000200000000000000000000000000000000000000000000000000000000000000001000000000000" + - "0000000000000000000000000000000000000000000000000001000000000000000000000000000000000" + - "0000000000000000000000000000001616263640000000000000000000000000000000000000000000000" + - "0000000000616263640000000000000000000000000000000000000000000000000000000061626364000" + - "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + - "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + - "000000003e800000000000000000000000000000000000000000000000000000000000000010000000000" + - "0000000000000010020fcb72e27650651b05ed2ceca493bc807ba40000000000000000000000000000000" + - "0000000000000000000000000000001600000000000000000000000000000000000000000000000000000" + - "00000000000100000000000000000000000010020fcb72e27650651b05ed2ceca493bc807ba4000000000" + - "0000000000000000000000000000000000000000000000000000002000000000000000000000000000000" + - "0000000000000000000000000000000001") - - require.Nil(t, err) - require.Equal(t, kgv2, encoded2) -} - func TestUnpackTxListBytes(t *testing.T) { _, err := UnpackTxListBytes(randomBytes(1024)) require.NotNil(t, err) diff --git a/bindings/encoding/struct.go b/bindings/encoding/struct.go index d0f61fd59..a3f848b8c 100644 --- a/bindings/encoding/struct.go +++ b/bindings/encoding/struct.go @@ -8,10 +8,7 @@ import ( "github.com/ethereum/go-ethereum/core/types" ) -var ( - OracleProverAddress = common.HexToAddress("0x0000000000000000000000000000000000000001") -) - +// BlockHeader represents an Ethereum block header. type BlockHeader struct { ParentHash [32]byte OmmersHash [32]byte @@ -31,34 +28,30 @@ type BlockHeader struct { BaseFeePerGas *big.Int } -type TaikoL1Evidence struct { +// BlockEvidence should be same with TaikoData.BlockEvidence. +type BlockEvidence struct { MetaHash [32]byte - BlockHash [32]byte ParentHash [32]byte + BlockHash [32]byte SignalRoot [32]byte Graffiti [32]byte - Prover common.Address + Tier uint16 Proofs []byte } -type TaikoL1BlockMetadataInput struct { - TxListHash [32]byte - Proposer common.Address - TxListByteStart *big.Int - TxListByteEnd *big.Int - CacheTxListInfo bool +// TierFee should be same with TaikoData.TierFee. +type TierFee struct { + Tier uint16 + Fee *big.Int } +// ProverAssignment should be same with TaikoData.ProverAssignment. type ProverAssignment struct { - Prover common.Address - Expiry uint64 - Data []byte -} - -type ProposeBlockData struct { - Input TaikoL1BlockMetadataInput `json:"input"` - Fee *big.Int `json:"fee"` - Expiry uint64 `json:"expiry"` + Prover common.Address + FeeToken common.Address + TierFees []*TierFee + Expiry uint64 + Signature []byte } // FromGethHeader converts a GETH *types.Header to *BlockHeader. diff --git a/bindings/encoding/struct_test.go b/bindings/encoding/struct_test.go index 00f05a105..03355fbab 100644 --- a/bindings/encoding/struct_test.go +++ b/bindings/encoding/struct_test.go @@ -11,7 +11,6 @@ import ( "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/log" "github.com/stretchr/testify/require" - "github.com/taikoxyz/taiko-client/bindings" ) var ( @@ -33,26 +32,6 @@ var ( Nonce: types.EncodeNonce(rand.Uint64()), BaseFee: new(big.Int).SetUint64(rand.Uint64()), } - testMetaInput = TaikoL1BlockMetadataInput{ - Proposer: common.BytesToAddress(randomHash().Bytes()), - TxListHash: randomHash(), - TxListByteStart: common.Big0, - TxListByteEnd: common.Big0, - CacheTxListInfo: false, - } - testMeta = bindings.TaikoDataBlockMetadata{ - Id: rand.Uint64(), - Timestamp: uint64(time.Now().Unix()), - L1Height: rand.Uint64(), - L1Hash: randomHash(), - MixHash: randomHash(), - TxListHash: randomHash(), - TxListByteStart: common.Big0, - TxListByteEnd: common.Big256, - GasLimit: rand.Uint32(), - Proposer: common.BytesToAddress(randomHash().Bytes()), - DepositsProcessed: []bindings.TaikoDataEthDeposit{}, - } ) func TestFromGethHeader(t *testing.T) {