introduce slimReceipt type

This commit is contained in:
Sina Mahmoodi 2026-02-06 13:09:46 +01:00
parent adc2337b63
commit ca967ad1bb
5 changed files with 75 additions and 9 deletions

View file

@ -424,3 +424,33 @@ func EncodeBlockReceiptLists(receipts []Receipts) []rlp.RawValue {
}
return result
}
// SlimReceipt is a wrapper around a Receipt with RLP serialization that omits
// the Bloom field and includes the tx type. Used for era files.
type SlimReceipt Receipt
type slimReceiptRLP struct {
Type uint8
StatusEncoding []byte
CumulativeGasUsed uint64
Logs []*Log
}
// EncodeRLP implements rlp.Encoder, encoding the receipt as
// [tx-type, post-state-or-status, cumulative-gas, logs].
func (r *SlimReceipt) EncodeRLP(w io.Writer) error {
data := &slimReceiptRLP{r.Type, (*Receipt)(r).statusEncoding(), r.CumulativeGasUsed, r.Logs}
return rlp.Encode(w, data)
}
// DecodeRLP implements rlp.Decoder.
func (r *SlimReceipt) DecodeRLP(s *rlp.Stream) error {
var data slimReceiptRLP
if err := s.Decode(&data); err != nil {
return err
}
r.Type = data.Type
r.CumulativeGasUsed = data.CumulativeGasUsed
r.Logs = data.Logs
return (*Receipt)(r).setStatus(data.StatusEncoding)
}

View file

@ -512,6 +512,45 @@ func TestReceiptUnmarshalBinary(t *testing.T) {
}
}
func TestSlimReceiptEncodingDecoding(t *testing.T) {
tests := []*Receipt{
legacyReceipt,
accessListReceipt,
eip1559Receipt,
{
Type: BlobTxType,
Status: ReceiptStatusSuccessful,
CumulativeGasUsed: 100,
Logs: []*Log{},
},
}
for i, want := range tests {
enc, err := rlp.EncodeToBytes((*SlimReceipt)(want))
if err != nil {
t.Fatalf("test %d: encode error: %v", i, err)
}
got := new(SlimReceipt)
if err := rlp.DecodeBytes(enc, got); err != nil {
t.Fatalf("test %d: decode error: %v", i, err)
}
if got.Type != want.Type {
t.Errorf("test %d: Type mismatch: got %d, want %d", i, got.Type, want.Type)
}
if got.Status != want.Status {
t.Errorf("test %d: Status mismatch: got %d, want %d", i, got.Status, want.Status)
}
if !bytes.Equal(got.PostState, want.PostState) {
t.Errorf("test %d: PostState mismatch: got %x, want %x", i, got.PostState, want.PostState)
}
if got.CumulativeGasUsed != want.CumulativeGasUsed {
t.Errorf("test %d: CumulativeGasUsed mismatch: got %d, want %d", i, got.CumulativeGasUsed, want.CumulativeGasUsed)
}
if len(got.Logs) != len(want.Logs) {
t.Errorf("test %d: Logs length mismatch: got %d, want %d", i, len(got.Logs), len(want.Logs))
}
}
}
func clearComputedFieldsOnReceipts(receipts []*Receipt) []*Receipt {
r := make([]*Receipt, len(receipts))
for i, receipt := range receipts {

View file

@ -107,9 +107,9 @@ func (b *Builder) Add(block *types.Block, receipts types.Receipts, td *big.Int)
return fmt.Errorf("encode body: %w", err)
}
rs := make([]*types.ReceiptForStorage, len(receipts))
rs := make([]*types.SlimReceipt, len(receipts))
for i, receipt := range receipts {
rs[i] = (*types.ReceiptForStorage)(receipt)
rs[i] = (*types.SlimReceipt)(receipt)
}
er, err := rlp.EncodeToBytes(rs)
if err != nil {

View file

@ -100,7 +100,7 @@ func TestEraE(t *testing.T) {
blk := blockData{
header: mustEncode(&types.Header{Number: big.NewInt(int64(num)), Difficulty: big.NewInt(1)}),
body: mustEncode(&types.Body{Transactions: []*types.Transaction{types.NewTransaction(0, common.Address{byte(i)}, nil, 0, nil, nil)}}),
receipts: mustEncode([]types.ReceiptForStorage{{CumulativeGasUsed: uint64(i)}}),
receipts: mustEncode([]types.SlimReceipt{{CumulativeGasUsed: uint64(i)}}),
hash: common.Hash{byte(i)},
td: big.NewInt(int64(i + 1)),
difficulty: big.NewInt(1),
@ -118,7 +118,7 @@ func TestEraE(t *testing.T) {
blk := blockData{
header: mustEncode(&types.Header{Number: big.NewInt(int64(num)), Difficulty: big.NewInt(0)}),
body: mustEncode(&types.Body{}),
receipts: mustEncode([]types.ReceiptForStorage{}),
receipts: mustEncode([]types.SlimReceipt{}),
hash: common.Hash{byte(idx)},
difficulty: big.NewInt(0),
}
@ -306,7 +306,7 @@ func TestInitialTD(t *testing.T) {
// First block: difficulty=5, TD=10, so initial TD = 10-5 = 5.
header := mustEncode(&types.Header{Number: big.NewInt(0), Difficulty: big.NewInt(5)})
body := mustEncode(&types.Body{})
receipts := mustEncode([]types.ReceiptForStorage{})
receipts := mustEncode([]types.SlimReceipt{})
if err := builder.AddRLP(header, body, receipts, 0, common.Hash{0}, big.NewInt(10), big.NewInt(5)); err != nil {
t.Fatalf("error adding block: %v", err)

View file

@ -88,19 +88,16 @@ func (it *Iterator) Receipts() (types.Receipts, error) {
if it.inner.Receipts == nil {
return nil, errors.New("receipts must be nonnil")
}
var rs []*types.ReceiptForStorage
var rs []*types.SlimReceipt
if err := rlp.Decode(it.inner.Receipts, &rs); err != nil {
return nil, err
}
if len(rs) != len(block.Transactions()) {
return nil, errors.New("number of txs does not match receipts")
}
receipts := make([]*types.Receipt, len(rs))
for i, receipt := range rs {
receipts[i] = (*types.Receipt)(receipt)
receipts[i].Type = block.Transactions()[i].Type()
receipts[i].Bloom = types.CreateBloom(receipts[i])
}
return receipts, nil