From 004e5861cf996fadc4101c4f9102edc5141afd74 Mon Sep 17 00:00:00 2001 From: piersy Date: Thu, 20 Jun 2024 19:02:15 +0100 Subject: [PATCH] Handle migrated celo headers (#143) This PR updates the header encoding and decoding for celo blocks to be able to support data migrated from celo-blockchain. Our post gingerbread headers actually decode into the op-geth header structure without any changes. Since adding fields to the end of a struct does not cause rlp decoding to fail for previously encoded values. Our pre-gingerbread don't decode into the op-geth header structure because the pre-gingerbread headers miss fields from the middle of the struct so we need to handle those explicitly. The decision on how to decode is made based on introspecting the rlp and looking at the second field which is a hash (length 32 bytes) post-gingerbread, but an address (length 20 bytes) pre-gingerbread. The decision on how to encode is made based on the value of gasLimit if zero then it's a pre-gingerbread header. Additionally we needed to allow genesis blocks in a CeL2 migrated chain context (by checking if Cel2Time is set and non zero) that lack GasLimit and Difficulty because those fields were considered required by op-geth but not present in early Celo. Finally some tests that used blocks with zero gas limits needed to be updated since with a zero gas limit the different encoding was now breaking them, and adding a non zero gas limit meant the block hash changed. --- core/gen_genesis.go | 72 ++++---- core/genesis.go | 19 ++- core/types/celo_block.go | 154 ++++++++++++++++++ core/types/gen_header_rlp.go | 85 ---------- internal/ethapi/api_test.go | 24 +-- .../eth_getBlockByNumber-tag-latest.json | 2 +- ...h_getBlockByNumber-tag-pending-fullTx.json | 6 +- .../eth_getBlockByNumber-tag-pending.json | 4 +- .../eth_getHeaderByNumber-tag-pending.json | 4 +- rlp/celo_raw.go | 16 ++ rpc/subscription_test.go | 3 +- 11 files changed, 239 insertions(+), 150 deletions(-) create mode 100644 core/types/celo_block.go delete mode 100644 core/types/gen_header_rlp.go create mode 100644 rlp/celo_raw.go diff --git a/core/gen_genesis.go b/core/gen_genesis.go index 3a57ec65e8..f4aec12026 100644 --- a/core/gen_genesis.go +++ b/core/gen_genesis.go @@ -19,22 +19,22 @@ var _ = (*genesisSpecMarshaling)(nil) // MarshalJSON marshals as JSON. func (g Genesis) MarshalJSON() ([]byte, error) { type Genesis struct { - Config *params.ChainConfig `json:"config"` - Nonce math.HexOrDecimal64 `json:"nonce"` - Timestamp math.HexOrDecimal64 `json:"timestamp"` - ExtraData hexutil.Bytes `json:"extraData"` - GasLimit math.HexOrDecimal64 `json:"gasLimit" gencodec:"required"` - Difficulty *math.HexOrDecimal256 `json:"difficulty" gencodec:"required"` - Mixhash common.Hash `json:"mixHash"` - Coinbase common.Address `json:"coinbase"` + Config *params.ChainConfig `json:"config"` + Nonce math.HexOrDecimal64 `json:"nonce"` + Timestamp math.HexOrDecimal64 `json:"timestamp"` + ExtraData hexutil.Bytes `json:"extraData"` + GasLimit math.HexOrDecimal64 `json:"gasLimit"` + Difficulty *math.HexOrDecimal256 `json:"difficulty"` + Mixhash common.Hash `json:"mixHash"` + Coinbase common.Address `json:"coinbase"` Alloc map[common.UnprefixedAddress]types.Account `json:"alloc" gencodec:"required"` - Number math.HexOrDecimal64 `json:"number"` - GasUsed math.HexOrDecimal64 `json:"gasUsed"` - ParentHash common.Hash `json:"parentHash"` - BaseFee *math.HexOrDecimal256 `json:"baseFeePerGas"` - ExcessBlobGas *math.HexOrDecimal64 `json:"excessBlobGas"` - BlobGasUsed *math.HexOrDecimal64 `json:"blobGasUsed"` - StateHash *common.Hash `json:"stateHash,omitempty"` + Number math.HexOrDecimal64 `json:"number"` + GasUsed math.HexOrDecimal64 `json:"gasUsed"` + ParentHash common.Hash `json:"parentHash"` + BaseFee *math.HexOrDecimal256 `json:"baseFeePerGas"` + ExcessBlobGas *math.HexOrDecimal64 `json:"excessBlobGas"` + BlobGasUsed *math.HexOrDecimal64 `json:"blobGasUsed"` + StateHash *common.Hash `json:"stateHash,omitempty"` } var enc Genesis enc.Config = g.Config @@ -64,22 +64,22 @@ func (g Genesis) MarshalJSON() ([]byte, error) { // UnmarshalJSON unmarshals from JSON. func (g *Genesis) UnmarshalJSON(input []byte) error { type Genesis struct { - Config *params.ChainConfig `json:"config"` - Nonce *math.HexOrDecimal64 `json:"nonce"` - Timestamp *math.HexOrDecimal64 `json:"timestamp"` - ExtraData *hexutil.Bytes `json:"extraData"` - GasLimit *math.HexOrDecimal64 `json:"gasLimit" gencodec:"required"` - Difficulty *math.HexOrDecimal256 `json:"difficulty" gencodec:"required"` - Mixhash *common.Hash `json:"mixHash"` - Coinbase *common.Address `json:"coinbase"` - Alloc map[common.UnprefixedAddress]GenesisAccount `json:"alloc" gencodec:"required"` - Number *math.HexOrDecimal64 `json:"number"` - GasUsed *math.HexOrDecimal64 `json:"gasUsed"` - ParentHash *common.Hash `json:"parentHash"` - BaseFee *math.HexOrDecimal256 `json:"baseFeePerGas"` - ExcessBlobGas *math.HexOrDecimal64 `json:"excessBlobGas"` - BlobGasUsed *math.HexOrDecimal64 `json:"blobGasUsed"` - StateHash *common.Hash `json:"stateHash,omitempty"` + Config *params.ChainConfig `json:"config"` + Nonce *math.HexOrDecimal64 `json:"nonce"` + Timestamp *math.HexOrDecimal64 `json:"timestamp"` + ExtraData *hexutil.Bytes `json:"extraData"` + GasLimit *math.HexOrDecimal64 `json:"gasLimit"` + Difficulty *math.HexOrDecimal256 `json:"difficulty"` + Mixhash *common.Hash `json:"mixHash"` + Coinbase *common.Address `json:"coinbase"` + Alloc map[common.UnprefixedAddress]types.Account `json:"alloc" gencodec:"required"` + Number *math.HexOrDecimal64 `json:"number"` + GasUsed *math.HexOrDecimal64 `json:"gasUsed"` + ParentHash *common.Hash `json:"parentHash"` + BaseFee *math.HexOrDecimal256 `json:"baseFeePerGas"` + ExcessBlobGas *math.HexOrDecimal64 `json:"excessBlobGas"` + BlobGasUsed *math.HexOrDecimal64 `json:"blobGasUsed"` + StateHash *common.Hash `json:"stateHash,omitempty"` } var dec Genesis if err := json.Unmarshal(input, &dec); err != nil { @@ -97,14 +97,12 @@ func (g *Genesis) UnmarshalJSON(input []byte) error { if dec.ExtraData != nil { g.ExtraData = *dec.ExtraData } - if dec.GasLimit == nil { - return errors.New("missing required field 'gasLimit' for Genesis") + if dec.GasLimit != nil { + g.GasLimit = uint64(*dec.GasLimit) } - g.GasLimit = uint64(*dec.GasLimit) - if dec.Difficulty == nil { - return errors.New("missing required field 'difficulty' for Genesis") + if dec.Difficulty != nil { + g.Difficulty = (*big.Int)(dec.Difficulty) } - g.Difficulty = (*big.Int)(dec.Difficulty) if dec.Mixhash != nil { g.Mixhash = *dec.Mixhash } diff --git a/core/genesis.go b/core/genesis.go index acf97bf59c..d69d9ed261 100644 --- a/core/genesis.go +++ b/core/genesis.go @@ -60,8 +60,8 @@ type Genesis struct { Nonce uint64 `json:"nonce"` Timestamp uint64 `json:"timestamp"` ExtraData []byte `json:"extraData"` - GasLimit uint64 `json:"gasLimit" gencodec:"required"` - Difficulty *big.Int `json:"difficulty" gencodec:"required"` + GasLimit uint64 `json:"gasLimit"` + Difficulty *big.Int `json:"difficulty"` Mixhash common.Hash `json:"mixHash"` Coinbase common.Address `json:"coinbase"` Alloc types.GenesisAlloc `json:"alloc" gencodec:"required"` @@ -475,11 +475,16 @@ func (g *Genesis) ToBlock() *types.Block { Coinbase: g.Coinbase, Root: root, } - if g.GasLimit == 0 { - head.GasLimit = params.GenesisGasLimit - } - if g.Difficulty == nil && g.Mixhash == (common.Hash{}) { - head.Difficulty = params.GenesisDifficulty + // Don't set defaults for gas limit and difficulty for migrated celo chains. + // I.E. when Cel2Time is set & non zero. Since migrated celo chains can + // have gas limit and difficulty unset in the genesis. + if g.Config.Cel2Time == nil || g.Config.IsCel2(0) { + if g.GasLimit == 0 { + head.GasLimit = params.GenesisGasLimit + } + if g.Difficulty == nil && g.Mixhash == (common.Hash{}) { + head.Difficulty = params.GenesisDifficulty + } } if g.Config != nil && g.Config.IsLondon(common.Big0) { if g.BaseFee != nil { diff --git a/core/types/celo_block.go b/core/types/celo_block.go new file mode 100644 index 0000000000..07aebf7139 --- /dev/null +++ b/core/types/celo_block.go @@ -0,0 +1,154 @@ +package types + +import ( + "io" + "math/big" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/rlp" +) + +type IstanbulExtra rlp.RawValue + +type beforeGingerbreadHeader struct { + ParentHash common.Hash `json:"parentHash" gencodec:"required"` + Coinbase common.Address `json:"miner" gencodec:"required"` + Root common.Hash `json:"stateRoot" gencodec:"required"` + TxHash common.Hash `json:"transactionsRoot" gencodec:"required"` + ReceiptHash common.Hash `json:"receiptsRoot" gencodec:"required"` + Bloom Bloom `json:"logsBloom" gencodec:"required"` + Number *big.Int `json:"number" gencodec:"required"` + GasUsed uint64 `json:"gasUsed" gencodec:"required"` + Time uint64 `json:"timestamp" gencodec:"required"` + Extra []byte `json:"extraData" gencodec:"required"` +} + +// This type is required to avoid an infinite loop when decoding +type afterGingerbreadHeader Header + +func (h *Header) DecodeRLP(s *rlp.Stream) error { + var raw rlp.RawValue + err := s.Decode(&raw) + if err != nil { + return err + } + + preGingerbread, err := isPreGingerbreadHeader(raw) + if err != nil { + return err + } + + if preGingerbread { // Address + // Before gingerbread + decodedHeader := beforeGingerbreadHeader{} + err = rlp.DecodeBytes(raw, &decodedHeader) + + h.ParentHash = decodedHeader.ParentHash + h.Coinbase = decodedHeader.Coinbase + h.Root = decodedHeader.Root + h.TxHash = decodedHeader.TxHash + h.ReceiptHash = decodedHeader.ReceiptHash + h.Bloom = decodedHeader.Bloom + h.Number = decodedHeader.Number + h.GasUsed = decodedHeader.GasUsed + h.Time = decodedHeader.Time + h.Extra = decodedHeader.Extra + } else { + // After gingerbread + decodedHeader := afterGingerbreadHeader{} + err = rlp.DecodeBytes(raw, &decodedHeader) + + h.ParentHash = decodedHeader.ParentHash + h.UncleHash = decodedHeader.UncleHash + h.Coinbase = decodedHeader.Coinbase + h.Root = decodedHeader.Root + h.TxHash = decodedHeader.TxHash + h.ReceiptHash = decodedHeader.ReceiptHash + h.Bloom = decodedHeader.Bloom + h.Difficulty = decodedHeader.Difficulty + h.Number = decodedHeader.Number + h.GasLimit = decodedHeader.GasLimit + h.GasUsed = decodedHeader.GasUsed + h.Time = decodedHeader.Time + h.Extra = decodedHeader.Extra + h.MixDigest = decodedHeader.MixDigest + h.Nonce = decodedHeader.Nonce + h.BaseFee = decodedHeader.BaseFee + h.WithdrawalsHash = decodedHeader.WithdrawalsHash + h.BlobGasUsed = decodedHeader.BlobGasUsed + h.ExcessBlobGas = decodedHeader.ExcessBlobGas + h.ParentBeaconRoot = decodedHeader.ParentBeaconRoot + } + + return err +} + +// EncodeRLP implements encodes the Header to an RLP data stream. +func (h *Header) EncodeRLP(w io.Writer) error { + // We check for a pre gingerbread header by looking for (GasLimit == 0) + // here. We don't use Difficulty because CopyHeader can end up setting a + // nil Difficulty to a zero difficulty, so testing for nil difficulty is + // not reliable, and post gingerbread difficulty is hardcoded to zero. Also + // testing for base fee is not reliable because some older eth blocks had + // no base fee and they are used in some tests. + if h.GasLimit == 0 { + // Encode the header + encodedHeader := beforeGingerbreadHeader{ + ParentHash: h.ParentHash, + Coinbase: h.Coinbase, + Root: h.Root, + TxHash: h.TxHash, + ReceiptHash: h.ReceiptHash, + Bloom: h.Bloom, + Number: h.Number, + GasUsed: h.GasUsed, + Time: h.Time, + Extra: h.Extra, + } + + return rlp.Encode(w, &encodedHeader) + } + + // After gingerbread + encodedHeader := afterGingerbreadHeader{ + ParentHash: h.ParentHash, + UncleHash: h.UncleHash, + Coinbase: h.Coinbase, + Root: h.Root, + TxHash: h.TxHash, + ReceiptHash: h.ReceiptHash, + Bloom: h.Bloom, + Difficulty: h.Difficulty, + Number: h.Number, + GasLimit: h.GasLimit, + GasUsed: h.GasUsed, + Time: h.Time, + Extra: h.Extra, + MixDigest: h.MixDigest, + Nonce: h.Nonce, + BaseFee: h.BaseFee, + WithdrawalsHash: h.WithdrawalsHash, + BlobGasUsed: h.BlobGasUsed, + ExcessBlobGas: h.ExcessBlobGas, + ParentBeaconRoot: h.ParentBeaconRoot, + } + + return rlp.Encode(w, &encodedHeader) +} + +// isPreGingerbreadHeader introspects the header rlp to check the length of the +// second element of the list (the first element describes the list). Pre +// gingerbread the second element of a header is an address which is 20 bytes +// long, post gingerbread the second element is a hash which is 32 bytes long. +func isPreGingerbreadHeader(buf []byte) (bool, error) { + var contentSize uint64 + var err error + for i := 0; i < 3; i++ { + buf, _, _, contentSize, err = rlp.ReadNext(buf) + if err != nil { + return false, err + } + } + + return contentSize == common.AddressLength, nil +} diff --git a/core/types/gen_header_rlp.go b/core/types/gen_header_rlp.go deleted file mode 100644 index ed6a1a002c..0000000000 --- a/core/types/gen_header_rlp.go +++ /dev/null @@ -1,85 +0,0 @@ -// Code generated by rlpgen. DO NOT EDIT. - -package types - -import "github.com/ethereum/go-ethereum/rlp" -import "io" - -func (obj *Header) EncodeRLP(_w io.Writer) error { - w := rlp.NewEncoderBuffer(_w) - _tmp0 := w.List() - w.WriteBytes(obj.ParentHash[:]) - w.WriteBytes(obj.UncleHash[:]) - w.WriteBytes(obj.Coinbase[:]) - w.WriteBytes(obj.Root[:]) - w.WriteBytes(obj.TxHash[:]) - w.WriteBytes(obj.ReceiptHash[:]) - w.WriteBytes(obj.Bloom[:]) - if obj.Difficulty == nil { - w.Write(rlp.EmptyString) - } else { - if obj.Difficulty.Sign() == -1 { - return rlp.ErrNegativeBigInt - } - w.WriteBigInt(obj.Difficulty) - } - if obj.Number == nil { - w.Write(rlp.EmptyString) - } else { - if obj.Number.Sign() == -1 { - return rlp.ErrNegativeBigInt - } - w.WriteBigInt(obj.Number) - } - w.WriteUint64(obj.GasLimit) - w.WriteUint64(obj.GasUsed) - w.WriteUint64(obj.Time) - w.WriteBytes(obj.Extra) - w.WriteBytes(obj.MixDigest[:]) - w.WriteBytes(obj.Nonce[:]) - _tmp1 := obj.BaseFee != nil - _tmp2 := obj.WithdrawalsHash != nil - _tmp3 := obj.BlobGasUsed != nil - _tmp4 := obj.ExcessBlobGas != nil - _tmp5 := obj.ParentBeaconRoot != nil - if _tmp1 || _tmp2 || _tmp3 || _tmp4 || _tmp5 { - if obj.BaseFee == nil { - w.Write(rlp.EmptyString) - } else { - if obj.BaseFee.Sign() == -1 { - return rlp.ErrNegativeBigInt - } - w.WriteBigInt(obj.BaseFee) - } - } - if _tmp2 || _tmp3 || _tmp4 || _tmp5 { - if obj.WithdrawalsHash == nil { - w.Write([]byte{0x80}) - } else { - w.WriteBytes(obj.WithdrawalsHash[:]) - } - } - if _tmp3 || _tmp4 || _tmp5 { - if obj.BlobGasUsed == nil { - w.Write([]byte{0x80}) - } else { - w.WriteUint64((*obj.BlobGasUsed)) - } - } - if _tmp4 || _tmp5 { - if obj.ExcessBlobGas == nil { - w.Write([]byte{0x80}) - } else { - w.WriteUint64((*obj.ExcessBlobGas)) - } - } - if _tmp5 { - if obj.ParentBeaconRoot == nil { - w.Write([]byte{0x80}) - } else { - w.WriteBytes(obj.ParentBeaconRoot[:]) - } - } - w.ListEnd(_tmp0) - return w.Flush() -} diff --git a/internal/ethapi/api_test.go b/internal/ethapi/api_test.go index e1a900b08e..adee570938 100644 --- a/internal/ethapi/api_test.go +++ b/internal/ethapi/api_test.go @@ -1559,7 +1559,7 @@ func TestRPCMarshalBlock(t *testing.T) { } txs = append(txs, tx) } - block := types.NewBlock(&types.Header{Number: big.NewInt(100)}, txs, nil, nil, blocktest.NewHasher()) + block := types.NewBlock(&types.Header{Number: big.NewInt(100), GasLimit: 10}, txs, nil, nil, blocktest.NewHasher()) var testSuite = []struct { inclTx bool @@ -1573,9 +1573,9 @@ func TestRPCMarshalBlock(t *testing.T) { want: `{ "difficulty": "0x0", "extraData": "0x", - "gasLimit": "0x0", + "gasLimit": "0xa", "gasUsed": "0x0", - "hash": "0x9b73c83b25d0faf7eab854e3684c7e394336d6e135625aafa5c183f27baa8fee", + "hash": "0x7117849518bf9484dae1b1e0aeb9f37b4fa81550061e2057614bec1a022e4596", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "miner": "0x0000000000000000000000000000000000000000", "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", @@ -1598,9 +1598,9 @@ func TestRPCMarshalBlock(t *testing.T) { want: `{ "difficulty": "0x0", "extraData": "0x", - "gasLimit": "0x0", + "gasLimit": "0xa", "gasUsed": "0x0", - "hash": "0x9b73c83b25d0faf7eab854e3684c7e394336d6e135625aafa5c183f27baa8fee", + "hash": "0x7117849518bf9484dae1b1e0aeb9f37b4fa81550061e2057614bec1a022e4596", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "miner": "0x0000000000000000000000000000000000000000", "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", @@ -1629,9 +1629,9 @@ func TestRPCMarshalBlock(t *testing.T) { want: `{ "difficulty": "0x0", "extraData": "0x", - "gasLimit": "0x0", + "gasLimit": "0xa", "gasUsed": "0x0", - "hash": "0x9b73c83b25d0faf7eab854e3684c7e394336d6e135625aafa5c183f27baa8fee", + "hash": "0x7117849518bf9484dae1b1e0aeb9f37b4fa81550061e2057614bec1a022e4596", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "miner": "0x0000000000000000000000000000000000000000", "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", @@ -1645,7 +1645,7 @@ func TestRPCMarshalBlock(t *testing.T) { "timestamp": "0x0", "transactions": [ { - "blockHash": "0x9b73c83b25d0faf7eab854e3684c7e394336d6e135625aafa5c183f27baa8fee", + "blockHash": "0x7117849518bf9484dae1b1e0aeb9f37b4fa81550061e2057614bec1a022e4596", "blockNumber": "0x64", "from": "0x0000000000000000000000000000000000000000", "gas": "0x457", @@ -1665,7 +1665,7 @@ func TestRPCMarshalBlock(t *testing.T) { "yParity": "0x0" }, { - "blockHash": "0x9b73c83b25d0faf7eab854e3684c7e394336d6e135625aafa5c183f27baa8fee", + "blockHash": "0x7117849518bf9484dae1b1e0aeb9f37b4fa81550061e2057614bec1a022e4596", "blockNumber": "0x64", "from": "0x0000000000000000000000000000000000000000", "gas": "0x457", @@ -1683,7 +1683,7 @@ func TestRPCMarshalBlock(t *testing.T) { "s": "0x0" }, { - "blockHash": "0x9b73c83b25d0faf7eab854e3684c7e394336d6e135625aafa5c183f27baa8fee", + "blockHash": "0x7117849518bf9484dae1b1e0aeb9f37b4fa81550061e2057614bec1a022e4596", "blockNumber": "0x64", "from": "0x0000000000000000000000000000000000000000", "gas": "0x457", @@ -1703,7 +1703,7 @@ func TestRPCMarshalBlock(t *testing.T) { "yParity": "0x0" }, { - "blockHash": "0x9b73c83b25d0faf7eab854e3684c7e394336d6e135625aafa5c183f27baa8fee", + "blockHash": "0x7117849518bf9484dae1b1e0aeb9f37b4fa81550061e2057614bec1a022e4596", "blockNumber": "0x64", "from": "0x0000000000000000000000000000000000000000", "gas": "0x457", @@ -1777,7 +1777,7 @@ func TestRPCGetBlockOrHeader(t *testing.T) { Address: common.Address{0x12, 0x34}, Amount: 10, } - pending = types.NewBlockWithWithdrawals(&types.Header{Number: big.NewInt(11), Time: 42}, []*types.Transaction{tx}, nil, nil, []*types.Withdrawal{withdrawal}, blocktest.NewHasher()) + pending = types.NewBlockWithWithdrawals(&types.Header{Number: big.NewInt(11), Time: 42, GasLimit: 10}, []*types.Transaction{tx}, nil, nil, []*types.Withdrawal{withdrawal}, blocktest.NewHasher()) ) backend := newTestBackend(t, genBlocks, genesis, ethash.NewFaker(), func(i int, b *core.BlockGen) { // Transfer from account[0] to account[1] diff --git a/internal/ethapi/testdata/eth_getBlockByNumber-tag-latest.json b/internal/ethapi/testdata/eth_getBlockByNumber-tag-latest.json index 6e914e37d0..46d3034f28 100644 --- a/internal/ethapi/testdata/eth_getBlockByNumber-tag-latest.json +++ b/internal/ethapi/testdata/eth_getBlockByNumber-tag-latest.json @@ -22,4 +22,4 @@ ], "transactionsRoot": "0xb0893d21a4a44dc26a962a6e91abae66df87fb61ac9c60e936aee89c76331445", "uncles": [] -} \ No newline at end of file +} diff --git a/internal/ethapi/testdata/eth_getBlockByNumber-tag-pending-fullTx.json b/internal/ethapi/testdata/eth_getBlockByNumber-tag-pending-fullTx.json index 7087932286..f4b5698938 100644 --- a/internal/ethapi/testdata/eth_getBlockByNumber-tag-pending-fullTx.json +++ b/internal/ethapi/testdata/eth_getBlockByNumber-tag-pending-fullTx.json @@ -1,7 +1,7 @@ { "difficulty": "0x0", "extraData": "0x", - "gasLimit": "0x0", + "gasLimit": "0xa", "gasUsed": "0x0", "hash": null, "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", @@ -18,7 +18,7 @@ "totalDifficulty": null, "transactions": [ { - "blockHash": "0x6cebd9f966ea686f44b981685e3f0eacea28591a7a86d7fbbe521a86e9f81165", + "blockHash": "0x0a6761c1616a9ef71352fa9b7169f0ca379397c73516f32f9cc5f414663b3412", "blockNumber": "0xb", "from": "0x0000000000000000000000000000000000000000", "gas": "0x457", @@ -47,4 +47,4 @@ } ], "withdrawalsRoot": "0x73d756269cdfc22e7e17a3548e36f42f750ca06d7e3cd98d1b6d0eb5add9dc84" -} \ No newline at end of file +} diff --git a/internal/ethapi/testdata/eth_getBlockByNumber-tag-pending.json b/internal/ethapi/testdata/eth_getBlockByNumber-tag-pending.json index c0e2b07bb8..688c8e8ff6 100644 --- a/internal/ethapi/testdata/eth_getBlockByNumber-tag-pending.json +++ b/internal/ethapi/testdata/eth_getBlockByNumber-tag-pending.json @@ -1,7 +1,7 @@ { "difficulty": "0x0", "extraData": "0x", - "gasLimit": "0x0", + "gasLimit": "0xa", "gasUsed": "0x0", "hash": null, "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", @@ -30,4 +30,4 @@ } ], "withdrawalsRoot": "0x73d756269cdfc22e7e17a3548e36f42f750ca06d7e3cd98d1b6d0eb5add9dc84" -} \ No newline at end of file +} diff --git a/internal/ethapi/testdata/eth_getHeaderByNumber-tag-pending.json b/internal/ethapi/testdata/eth_getHeaderByNumber-tag-pending.json index da177f2189..35d27ef88b 100644 --- a/internal/ethapi/testdata/eth_getHeaderByNumber-tag-pending.json +++ b/internal/ethapi/testdata/eth_getHeaderByNumber-tag-pending.json @@ -1,7 +1,7 @@ { "difficulty": "0x0", "extraData": "0x", - "gasLimit": "0x0", + "gasLimit": "0xa", "gasUsed": "0x0", "hash": null, "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", @@ -17,4 +17,4 @@ "totalDifficulty": null, "transactionsRoot": "0x98d9f6dd0aa479c0fb448f2627e9f1964aca699fccab8f6e95861547a4699e37", "withdrawalsRoot": "0x73d756269cdfc22e7e17a3548e36f42f750ca06d7e3cd98d1b6d0eb5add9dc84" -} \ No newline at end of file +} diff --git a/rlp/celo_raw.go b/rlp/celo_raw.go new file mode 100644 index 0000000000..de024d3f5d --- /dev/null +++ b/rlp/celo_raw.go @@ -0,0 +1,16 @@ +package rlp + +// ReadNext reads the next RLP item from the given buffer and returns the remaining buffer, +// the kind of the item, the size of the tag, the size of the content, and any error encountered. +func ReadNext(buf []byte) (remaining []byte, kind Kind, tagsize, contentsize uint64, err error) { + remaining = buf + kind, tagsize, contentsize, err = readKind(remaining) + if err != nil { + return nil, 0, 0, 0, err + } + remaining = remaining[tagsize:] + if kind != List { + remaining = remaining[contentsize:] + } + return +} diff --git a/rpc/subscription_test.go b/rpc/subscription_test.go index 3a131c8e6b..f96ed423e4 100644 --- a/rpc/subscription_test.go +++ b/rpc/subscription_test.go @@ -270,10 +270,11 @@ func TestNotify(t *testing.T) { msg := &types.Header{ ParentHash: common.HexToHash("0x01"), Number: big.NewInt(100), + GasLimit: 10, } notifier.Notify(id, msg) have := strings.TrimSpace(out.String()) - want := `{"jsonrpc":"2.0","method":"_subscription","params":{"subscription":"test","result":{"parentHash":"0x0000000000000000000000000000000000000000000000000000000000000001","sha3Uncles":"0x0000000000000000000000000000000000000000000000000000000000000000","miner":"0x0000000000000000000000000000000000000000","stateRoot":"0x0000000000000000000000000000000000000000000000000000000000000000","transactionsRoot":"0x0000000000000000000000000000000000000000000000000000000000000000","receiptsRoot":"0x0000000000000000000000000000000000000000000000000000000000000000","logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","difficulty":null,"number":"0x64","gasLimit":"0x0","gasUsed":"0x0","timestamp":"0x0","extraData":"0x","mixHash":"0x0000000000000000000000000000000000000000000000000000000000000000","nonce":"0x0000000000000000","baseFeePerGas":null,"withdrawalsRoot":null,"blobGasUsed":null,"excessBlobGas":null,"parentBeaconBlockRoot":null,"hash":"0xe5fb877dde471b45b9742bb4bb4b3d74a761e2fb7cb849a3d2b687eed90fb604"}}}` + want := `{"jsonrpc":"2.0","method":"_subscription","params":{"subscription":"test","result":{"parentHash":"0x0000000000000000000000000000000000000000000000000000000000000001","sha3Uncles":"0x0000000000000000000000000000000000000000000000000000000000000000","miner":"0x0000000000000000000000000000000000000000","stateRoot":"0x0000000000000000000000000000000000000000000000000000000000000000","transactionsRoot":"0x0000000000000000000000000000000000000000000000000000000000000000","receiptsRoot":"0x0000000000000000000000000000000000000000000000000000000000000000","logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","difficulty":null,"number":"0x64","gasLimit":"0xa","gasUsed":"0x0","timestamp":"0x0","extraData":"0x","mixHash":"0x0000000000000000000000000000000000000000000000000000000000000000","nonce":"0x0000000000000000","baseFeePerGas":null,"withdrawalsRoot":null,"blobGasUsed":null,"excessBlobGas":null,"parentBeaconBlockRoot":null,"hash":"0x98d8242410614702f0263d5f204c421912343ccad5a9ceee8989fda3ec21a1db"}}}` if have != want { t.Errorf("have:\n%v\nwant:\n%v\n", have, want) }