Skip to content
This repository was archived by the owner on Nov 25, 2025. It is now read-only.

Commit 787b67d

Browse files
committed
feat(core/types): Body hooks for RLP encoding
1 parent 3ff7dea commit 787b67d

File tree

5 files changed

+98
-12
lines changed

5 files changed

+98
-12
lines changed

core/rawdb/accessors_chain.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -522,7 +522,8 @@ func ReadBlock(db ethdb.Reader, hash common.Hash, number uint64) *types.Block {
522522
if body == nil {
523523
return nil
524524
}
525-
return types.NewBlockWithHeader(header).WithBody(body.Transactions, body.Uncles).WithExtData(body.Version, body.ExtData)
525+
bodyExtra := types.GetBodyExtra(body)
526+
return types.NewBlockWithHeader(header).WithBody(body.Transactions, body.Uncles).WithExtData(bodyExtra.Version, bodyExtra.ExtData)
526527
}
527528

528529
// WriteBlock serializes a block into the database, header and body separately.

core/types/block.go

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -37,15 +37,6 @@ import (
3737
"github.com/ava-labs/libevm/rlp"
3838
)
3939

40-
// Body is a simple (mutable, non-safe) data container for storing and moving
41-
// a block's data contents (transactions and uncles) together.
42-
type Body struct {
43-
Transactions []*Transaction
44-
Uncles []*Header
45-
Version uint32
46-
ExtData *[]byte `rlp:"nil"`
47-
}
48-
4940
// Block represents an Ethereum block.
5041
//
5142
// Note the Block type tries to be 'immutable', and contains certain caches that rely
@@ -152,7 +143,15 @@ func (b *Block) EncodeRLP(w io.Writer) error {
152143
// Body returns the non-header content of the block.
153144
// Note the returned data is not an independent copy.
154145
func (b *Block) Body() *Body {
155-
return &Body{b.transactions, b.uncles, b.version, b.extdata}
146+
body := &Body{
147+
Transactions: b.transactions,
148+
Uncles: b.uncles,
149+
}
150+
extra := &BodyExtra{
151+
Version: b.version,
152+
ExtData: b.extdata,
153+
}
154+
return WithBodyExtra(body, extra)
156155
}
157156

158157
// Accessors for body data. These do not return a copy because the content

core/types/body_ext.go

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
// (c) 2024, Ava Labs, Inc. All rights reserved.
2+
// See the file LICENSE for licensing terms.
3+
4+
package types
5+
6+
import (
7+
ethtypes "github.com/ava-labs/libevm/core/types"
8+
"github.com/ava-labs/libevm/rlp"
9+
)
10+
11+
func GetBodyExtra(b *Body) *BodyExtra {
12+
return extras.Body.Get(b)
13+
}
14+
15+
func WithBodyExtra(b *Body, extra *BodyExtra) *Body {
16+
extras.Body.Set(b, extra)
17+
return b
18+
}
19+
20+
// BodyExtra is a struct that contains extra fields used by Avalanche
21+
// in the body.
22+
// This type uses BodySerializable to encode and decode the extra fields
23+
// along with the upstream type for compatibility with existing network blocks.
24+
type BodyExtra struct {
25+
Version uint32
26+
ExtData *[]byte
27+
28+
// Fields removed from geth:
29+
// - withdrawals Withdrawals
30+
}
31+
32+
func (b *BodyExtra) RLPFieldsForEncoding(body *Body) *rlp.Fields {
33+
return &rlp.Fields{
34+
Required: []any{
35+
body.Transactions,
36+
body.Uncles,
37+
b.Version,
38+
b.ExtData,
39+
},
40+
}
41+
}
42+
43+
func (b *BodyExtra) RLPFieldPointersForDecoding(body *Body) *rlp.Fields {
44+
return &rlp.Fields{
45+
Required: []any{
46+
&body.Transactions,
47+
&body.Uncles,
48+
&b.Version,
49+
rlp.Nillable(&b.ExtData), // equivalent to `rlp:"nil"`
50+
},
51+
}
52+
}
53+
54+
// bodySerializable defines the body in the Ethereum blockchain,
55+
// as it is to be serialized into RLP.
56+
type bodySerializable struct {
57+
Transactions []*Transaction
58+
Uncles []*Header
59+
Version uint32
60+
ExtData *[]byte `rlp:"nil"`
61+
}
62+
63+
// updateFromEth updates the [*bodySerializable] from the [*ethtypes.Body].
64+
func (b *bodySerializable) updateFromEth(eth *ethtypes.Body) {
65+
b.Transactions = eth.Transactions
66+
b.Uncles = eth.Uncles
67+
}
68+
69+
// updateToEth updates the [*ethtypes.Body] from the [*bodySerializable].
70+
func (b *bodySerializable) updateToEth(eth *ethtypes.Body) {
71+
eth.Transactions = b.Transactions
72+
eth.Uncles = b.Uncles
73+
}
74+
75+
// updateFromExtras updates the [*bodySerializable] from the [*BodyExtra].
76+
func (b *bodySerializable) updateFromExtras(extras *BodyExtra) {
77+
b.Version = extras.Version
78+
b.ExtData = extras.ExtData
79+
}
80+
81+
// updateToExtras updates the [*BodyExtra] from the [*bodySerializable].
82+
func (b *bodySerializable) updateToExtras(extras *BodyExtra) {
83+
extras.Version = b.Version
84+
extras.ExtData = b.ExtData
85+
}

core/types/imports.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ type (
1717
BlobTxSidecar = ethtypes.BlobTxSidecar
1818
BlockNonce = ethtypes.BlockNonce
1919
Bloom = ethtypes.Bloom
20+
Body = ethtypes.Body
2021
DynamicFeeTx = ethtypes.DynamicFeeTx
2122
Header = ethtypes.Header
2223
HomesteadSigner = ethtypes.HomesteadSigner

core/types/libevm.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,6 @@ import (
99

1010
var extras = ethtypes.RegisterExtras[
1111
HeaderExtra, *HeaderExtra,
12-
ethtypes.NOOPBodyHooks, *ethtypes.NOOPBodyHooks,
12+
BodyExtra, *BodyExtra,
1313
isMultiCoin,
1414
]()

0 commit comments

Comments
 (0)