From 36d10a9271251dc859d0f256d38af26a3778a920 Mon Sep 17 00:00:00 2001 From: curryxbo Date: Thu, 4 Sep 2025 23:24:32 +0800 Subject: [PATCH 1/3] support eip7702 --- go-ethereum | 2 +- node/types/blob.go | 223 +--------------------------------------- node/types/blob_test.go | 43 ++++++-- 3 files changed, 39 insertions(+), 229 deletions(-) diff --git a/go-ethereum b/go-ethereum index 151913b1..6f1d6b6d 160000 --- a/go-ethereum +++ b/go-ethereum @@ -1 +1 @@ -Subproject commit 151913b181b1dba79226e67fd1ccb595d8c60d92 +Subproject commit 6f1d6b6d7fbc9228e3be08e0fdb314fb4717e6c5 diff --git a/node/types/blob.go b/node/types/blob.go index 05070d7b..847e15eb 100644 --- a/node/types/blob.go +++ b/node/types/blob.go @@ -121,147 +121,8 @@ func CompressBatchBytes(batchBytes []byte) ([]byte, error) { return compressedBatchBytes, nil } -func EncodeTxsPayloadToBlob(batchBytes []byte) (*eth.BlobTxSidecar, error) { - if len(batchBytes) == 0 { - return MakeBlobTxSidecar(batchBytes) - } - compressedBatchBytes, err := zstd.CompressBatchBytes(batchBytes) - if err != nil { - return nil, err - } - return MakeBlobTxSidecar(compressedBatchBytes) -} - -// Deprecated: DecodeTxsFromBlob is recommended -func DecodeLegacyTxsFromBlob(b *kzg4844.Blob) (eth.Transactions, error) { - data, err := RetrieveBlobBytes(b) - if err != nil { - return nil, err - } - - // metadata || tx_payload - // metadata consists of num_chunks (2 bytes) and chunki_size (4 bytes per chunk) - dataReader := bytes.NewReader(data[2:]) - var txPayloadSize uint32 - for i := 0; i < 15; i++ { - var size uint32 - if err := binary.Read(dataReader, binary.BigEndian, size); err != nil { - return nil, err - } - txPayloadSize += size - } - txPayload := data[62 : 62+txPayloadSize] - - var byteOccupied int - var sizeBytes []byte - b3 := byte(txPayloadSize >> 16) - b2 := byte(txPayloadSize >> 8) - b1 := byte(txPayloadSize) - if b3 > 0 { - byteOccupied = 3 - sizeBytes = []byte{b3, b2, b1} - } else if b2 > 0 { - byteOccupied = 2 - sizeBytes = []byte{b2, b1} - } else { - byteOccupied = 1 - sizeBytes = []byte{b1} - } - - fistByte := byte(247 + byteOccupied) - simulatedRLP := append(append([]byte{fistByte}, sizeBytes...), txPayload...) - decoded := make([]*eth.Transaction, 0) - if err := rlp.DecodeBytes(simulatedRLP, &decoded); err != nil { - return nil, err - } - return decoded, nil -} - -func DecodeTxsFromBlob(blob *kzg4844.Blob) (eth.Transactions, error) { - if isEmptyBlob(blob) { - return eth.Transactions{}, nil - } - data, err := RetrieveBlobBytes(blob) - if err != nil { - return nil, err - } - batchBytes, err := zstd.DecompressBatchBytes(data) - if err != nil { - return nil, err - } - reader := bytes.NewReader(batchBytes) - txs := make(eth.Transactions, 0) - for { - var ( - firstByte byte - fullTxBytes []byte - innerTx eth.TxData - err error - ) - if err = binary.Read(reader, binary.BigEndian, &firstByte); err != nil { - // if the blob byte array is completely consumed, then break the loop - if err == io.EOF { - break - } - return nil, err - } - // zero byte is found after valid tx bytes, break the loop - if firstByte == 0 { - break - } - - switch firstByte { - case eth.AccessListTxType: - if err := binary.Read(reader, binary.BigEndian, &firstByte); err != nil { - return nil, err - } - innerTx = new(eth.AccessListTx) - case eth.DynamicFeeTxType: - if err := binary.Read(reader, binary.BigEndian, &firstByte); err != nil { - return nil, err - } - innerTx = new(eth.DynamicFeeTx) - default: - if firstByte <= 0xf7 { // legacy tx first byte must be greater than 0xf7(247) - return nil, fmt.Errorf("not supported tx type: %d", firstByte) - } - innerTx = new(eth.LegacyTx) - } - - // we support the tx types of LegacyTxType/AccessListTxType/DynamicFeeTxType - //if firstByte == eth.AccessListTxType || firstByte == eth.DynamicFeeTxType { - // // the firstByte here is used to indicate tx type, so skip it - // if err := binary.Read(reader, binary.BigEndian, &firstByte); err != nil { - // return nil, err - // } - //} else if firstByte <= 0xf7 { // legacy tx first byte must be greater than 0xf7(247) - // return nil, fmt.Errorf("not supported tx type: %d", firstByte) - //} - fullTxBytes, err = extractInnerTxFullBytes(firstByte, reader) - if err != nil { - return nil, err - } - if err = rlp.DecodeBytes(fullTxBytes, innerTx); err != nil { - return nil, err - } - txs = append(txs, eth.NewTx(innerTx)) - } - return txs, nil -} - -func DecodeBlocksFromBlob(blob *kzg4844.Blob) (eth.Transactions, error) { - if isEmptyBlob(blob) { - return eth.Transactions{}, nil - } - data, err := RetrieveBlobBytes(blob) - if err != nil { - return nil, err - } - batchBytes, err := zstd.DecompressBatchBytes(data) - if err != nil { - return nil, err - } - reader := bytes.NewReader(batchBytes) +func DecodeTxsFromBytes(txsBytes []byte) (eth.Transactions, error) { + reader := bytes.NewReader(txsBytes) txs := make(eth.Transactions, 0) for { var ( @@ -293,78 +154,11 @@ func DecodeBlocksFromBlob(blob *kzg4844.Blob) (eth.Transactions, error) { return nil, err } innerTx = new(eth.DynamicFeeTx) - default: - if firstByte <= 0xf7 { // legacy tx first byte must be greater than 0xf7(247) - return nil, fmt.Errorf("not supported tx type: %d", firstByte) - } - innerTx = new(eth.LegacyTx) - } - - // we support the tx types of LegacyTxType/AccessListTxType/DynamicFeeTxType - //if firstByte == eth.AccessListTxType || firstByte == eth.DynamicFeeTxType { - // // the firstByte here is used to indicate tx type, so skip it - // if err := binary.Read(reader, binary.BigEndian, &firstByte); err != nil { - // return nil, err - // } - //} else if firstByte <= 0xf7 { // legacy tx first byte must be greater than 0xf7(247) - // return nil, fmt.Errorf("not supported tx type: %d", firstByte) - //} - fullTxBytes, err = extractInnerTxFullBytes(firstByte, reader) - if err != nil { - return nil, err - } - if err = rlp.DecodeBytes(fullTxBytes, innerTx); err != nil { - return nil, err - } - txs = append(txs, eth.NewTx(innerTx)) - } - return txs, nil -} - -func DecodeTxsFromBytes(txsBytes []byte) (eth.Transactions, error) { - //if isEmptyBlob(blob) { - // return eth.Transactions{}, nil - //} - //data, err := RetrieveBlobBytes(blob) - //if err != nil { - // return nil, err - //} - //batchBytes, err := zstd.DecompressBatchBytes(data) - //if err != nil { - // return nil, err - //} - reader := bytes.NewReader(txsBytes) - txs := make(eth.Transactions, 0) - for { - var ( - firstByte byte - fullTxBytes []byte - innerTx eth.TxData - err error - ) - if err = binary.Read(reader, binary.BigEndian, &firstByte); err != nil { - // if the blob byte array is completely consumed, then break the loop - if err == io.EOF { - break - } - return nil, err - } - // zero byte is found after valid tx bytes, break the loop - if firstByte == 0 { - break - } - - switch firstByte { - case eth.AccessListTxType: + case eth.SetCodeTxType: if err := binary.Read(reader, binary.BigEndian, &firstByte); err != nil { return nil, err } - innerTx = new(eth.AccessListTx) - case eth.DynamicFeeTxType: - if err := binary.Read(reader, binary.BigEndian, &firstByte); err != nil { - return nil, err - } - innerTx = new(eth.DynamicFeeTx) + innerTx = new(eth.SetCodeTx) default: if firstByte <= 0xf7 { // legacy tx first byte must be greater than 0xf7(247) return nil, fmt.Errorf("not supported tx type: %d", firstByte) @@ -393,15 +187,6 @@ func DecodeTxsFromBytes(txsBytes []byte) (eth.Transactions, error) { return txs, nil } -func isEmptyBlob(blob *kzg4844.Blob) bool { - for _, b := range blob { - if b != 0 { - return false - } - } - return true -} - func extractInnerTxFullBytes(firstByte byte, reader io.Reader) ([]byte, error) { //the occupied byte length for storing the size of the following rlp encoded bytes sizeByteLen := firstByte - 0xf7 diff --git a/node/types/blob_test.go b/node/types/blob_test.go index 11f72476..570294f8 100644 --- a/node/types/blob_test.go +++ b/node/types/blob_test.go @@ -1,8 +1,8 @@ package types import ( + "github.com/holiman/uint256" "math/big" - "morph-l2/node/zstd" "testing" "github.com/morph-l2/go-ethereum/accounts/abi/bind" @@ -97,7 +97,31 @@ func generateContractTx(isLegacy bool) (*eth.Transaction, error) { return auth.Signer(address, contractTx) } -func TestDecodeTxsFromBlob(t *testing.T) { +func generateSetCodeTx() *eth.Transaction { + privKey, _ := crypto.GenerateKey() + address := crypto.PubkeyToAddress(privKey.PublicKey) + to := common.BigToAddress(big.NewInt(100)) + data := rand.Bytes(100) + inner := ð.SetCodeTx{ + ChainID: uint256.NewInt(2810), + Nonce: 1, + GasFeeCap: uint256.NewInt(1e10), + GasTipCap: uint256.NewInt(1e8), + Gas: 500000, + To: to, + Value: uint256.NewInt(1), + Data: data, + AccessList: []eth.AccessTuple{{ + Address: address, + StorageKeys: []common.Hash{common.BigToHash(big.NewInt(2))}, + }}, + AuthList: []eth.SetCodeAuthorization{}, + } + return eth.NewTx(inner) + +} + +func TestDecodeTxsFromBytes(t *testing.T) { transferTx, err := generateTransferTx(false) require.NoError(t, err) transferTxBz, err := transferTx.MarshalBinary() @@ -113,16 +137,17 @@ func TestDecodeTxsFromBlob(t *testing.T) { contractTxBz, err := contractTx.MarshalBinary() require.NoError(t, err) - cks := BatchData{ - txsPayload: append(append(transferTxBz, legacyContractTxBz...), contractTxBz...), - } - compressedBlobBytes, err := zstd.CompressBatchBytes(cks.TxsPayload()) + setCodeTx := generateSetCodeTx() require.NoError(t, err) - b, err := MakeBlobCanonical(compressedBlobBytes) + setCodeTxBz, err := setCodeTx.MarshalBinary() require.NoError(t, err) - txs, err := DecodeTxsFromBlob(b) + + cks := BatchData{ + txsPayload: append(append(append(transferTxBz, legacyContractTxBz...), contractTxBz...), setCodeTxBz...), + } + txs, err := DecodeTxsFromBytes(cks.TxsPayload()) require.NoError(t, err) - require.EqualValues(t, 3, txs.Len()) + require.EqualValues(t, 4, txs.Len()) require.EqualValues(t, transferTx.Hash(), txs[0].Hash()) require.EqualValues(t, legacyContractTx.Hash(), txs[1].Hash()) require.EqualValues(t, contractTx.Hash(), txs[2].Hash()) From b79e1fb0fba514ec9dd2857d45f1eb0f643908c0 Mon Sep 17 00:00:00 2001 From: curryxbo Date: Thu, 4 Sep 2025 23:28:27 +0800 Subject: [PATCH 2/3] make update --- go-ethereum | 2 +- node/go.mod | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/go-ethereum b/go-ethereum index 6f1d6b6d..cd8f50b0 160000 --- a/go-ethereum +++ b/go-ethereum @@ -1 +1 @@ -Subproject commit 6f1d6b6d7fbc9228e3be08e0fdb314fb4717e6c5 +Subproject commit cd8f50b096743a451f5f331b3878d97c663534cb diff --git a/node/go.mod b/node/go.mod index b28269b8..cf455592 100644 --- a/node/go.mod +++ b/node/go.mod @@ -9,6 +9,7 @@ require ( github.com/go-kit/kit v0.12.0 github.com/hashicorp/go-multierror v1.1.1 github.com/hashicorp/golang-lru v1.0.2 + github.com/holiman/uint256 v1.2.4 github.com/klauspost/compress v1.17.9 github.com/morph-l2/go-ethereum v1.10.14-0.20250424011308-f42440d1ace1 github.com/prometheus/client_golang v1.17.0 @@ -64,7 +65,6 @@ require ( github.com/hashicorp/go-bexpr v0.1.13 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/holiman/bloomfilter/v2 v2.0.3 // indirect - github.com/holiman/uint256 v1.2.4 // indirect github.com/huin/goupnp v1.3.0 // indirect github.com/iden3/go-iden3-crypto v0.0.16 // indirect github.com/inconshreveable/mousetrap v1.0.0 // indirect From 7196622ccb33ad24172ba7e7d812e698d4ea6811 Mon Sep 17 00:00:00 2001 From: curryxbo Date: Mon, 8 Sep 2025 10:18:29 +0800 Subject: [PATCH 3/3] fmt --- node/types/blob_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/node/types/blob_test.go b/node/types/blob_test.go index 570294f8..94c08318 100644 --- a/node/types/blob_test.go +++ b/node/types/blob_test.go @@ -1,10 +1,10 @@ package types import ( - "github.com/holiman/uint256" "math/big" "testing" + "github.com/holiman/uint256" "github.com/morph-l2/go-ethereum/accounts/abi/bind" "github.com/morph-l2/go-ethereum/common" eth "github.com/morph-l2/go-ethereum/core/types"