Skip to content

Commit

Permalink
Merge branch 'main' into BeginTemporalRo
Browse files Browse the repository at this point in the history
  • Loading branch information
AskAlexSharov committed Dec 9, 2024
2 parents a713f9e + eae12fb commit 2b6da7a
Show file tree
Hide file tree
Showing 6 changed files with 279 additions and 9 deletions.
1 change: 1 addition & 0 deletions ChangeLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ ChangeLog
### New features:

- Reduced `.idx` and `.efi` files size by 25% (require re-sync)
- Support: `debug_getRawReceipts`
- debian packages
- `--externalcl` support
- bor-mainnet can work on 32G machine
Expand Down
6 changes: 6 additions & 0 deletions core/types/hashing.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"bytes"
"fmt"
"io"
"sync"

"github.com/protolambda/ztyp/codec"

Expand All @@ -34,6 +35,11 @@ import (
"github.com/erigontech/erigon-lib/trie"
)

// encodeBufferPool holds temporary encoder buffers for DeriveSha and TX encoding.
var encodeBufferPool = sync.Pool{
New: func() interface{} { return new(bytes.Buffer) },
}

type DerivableList interface {
Len() int
EncodeIndex(i int, w *bytes.Buffer)
Expand Down
67 changes: 64 additions & 3 deletions core/types/receipt.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ import (

//(go:generate gencodec -type Receipt -field-override receiptMarshaling -out gen_receipt_json.go)

var errShortTypedReceipt = errors.New("typed receipt too short")

var (
receiptStatusFailedRLP = []byte{}
receiptStatusSuccessfulRLP = []byte{0x01}
Expand Down Expand Up @@ -123,14 +125,73 @@ func (r Receipt) EncodeRLP(w io.Writer) error {
if r.Type == LegacyTxType {
return rlp.Encode(w, data)
}
buf := new(bytes.Buffer)
buf.WriteByte(r.Type)
if err := rlp.Encode(buf, data); err != nil {
buf := encodeBufferPool.Get().(*bytes.Buffer)
defer encodeBufferPool.Put(buf)
buf.Reset()
if err := r.encodeTyped(data, buf); err != nil {
return err
}
return rlp.Encode(w, buf.Bytes())
}

// encodeTyped writes the canonical encoding of a typed receipt to w.
func (r *Receipt) encodeTyped(data *receiptRLP, w *bytes.Buffer) error {
w.WriteByte(r.Type)
return rlp.Encode(w, data)
}

// MarshalBinary returns the consensus encoding of the receipt.
func (r *Receipt) MarshalBinary() ([]byte, error) {
if r.Type == LegacyTxType {
return rlp.EncodeToBytes(r)
}
data := &receiptRLP{r.statusEncoding(), r.CumulativeGasUsed, r.Bloom, r.Logs}
var buf bytes.Buffer
err := r.encodeTyped(data, &buf)
return buf.Bytes(), err
}

// UnmarshalBinary decodes the consensus encoding of receipts.
// It supports legacy RLP receipts and EIP-2718 typed receipts.
func (r *Receipt) UnmarshalBinary(b []byte) error {
if len(b) > 0 && b[0] > 0x7f {
// It's a legacy receipt decode the RLP
var data receiptRLP
err := rlp.DecodeBytes(b, &data)
if err != nil {
return err
}
r.Type = LegacyTxType
return r.setFromRLP(data)
}
// It's an EIP2718 typed transaction envelope.
return r.decodeTyped(b)
}

func (r *Receipt) setFromRLP(data receiptRLP) error {
r.CumulativeGasUsed, r.Bloom, r.Logs = data.CumulativeGasUsed, data.Bloom, data.Logs
return r.setStatus(data.PostStateOrStatus)
}

// decodeTyped decodes a typed receipt from the canonical format.
func (r *Receipt) decodeTyped(b []byte) error {
if len(b) <= 1 {
return errShortTypedReceipt
}
switch b[0] {
case DynamicFeeTxType, AccessListTxType, BlobTxType:
var data receiptRLP
err := rlp.DecodeBytes(b[1:], &data)
if err != nil {
return err
}
r.Type = b[0]
return r.setFromRLP(data)
default:
return ErrTxTypeNotSupported
}
}

func (r *Receipt) decodePayload(s *rlp.Stream) error {
_, err := s.List()
if err != nil {
Expand Down
153 changes: 153 additions & 0 deletions core/types/receipt_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
"errors"
"math"
"math/big"
"reflect"
"testing"

"github.com/holiman/uint256"
Expand Down Expand Up @@ -405,3 +406,155 @@ func clearComputedFieldsOnLog(t *testing.T, log *Log) {
log.TxIndex = math.MaxUint32
log.Index = math.MaxUint32
}

func TestReceiptUnmarshalBinary(t *testing.T) {
legacyReceipt := &Receipt{
Status: ReceiptStatusFailed,
CumulativeGasUsed: 1,
Logs: []*Log{
{
Address: libcommon.BytesToAddress([]byte{0x11}),
Topics: []libcommon.Hash{libcommon.HexToHash("dead"), libcommon.HexToHash("beef")},
Data: []byte{0x01, 0x00, 0xff},
},
{
Address: libcommon.BytesToAddress([]byte{0x01, 0x11}),
Topics: []libcommon.Hash{libcommon.HexToHash("dead"), libcommon.HexToHash("beef")},
Data: []byte{0x01, 0x00, 0xff},
},
},
}
accessListReceipt := &Receipt{
Status: ReceiptStatusFailed,
CumulativeGasUsed: 1,
Logs: []*Log{
{
Address: libcommon.BytesToAddress([]byte{0x11}),
Topics: []libcommon.Hash{libcommon.HexToHash("dead"), libcommon.HexToHash("beef")},
Data: []byte{0x01, 0x00, 0xff},
},
{
Address: libcommon.BytesToAddress([]byte{0x01, 0x11}),
Topics: []libcommon.Hash{libcommon.HexToHash("dead"), libcommon.HexToHash("beef")},
Data: []byte{0x01, 0x00, 0xff},
},
},
Type: AccessListTxType,
}
eip1559Receipt := &Receipt{
Status: ReceiptStatusFailed,
CumulativeGasUsed: 1,
Logs: []*Log{
{
Address: libcommon.BytesToAddress([]byte{0x11}),
Topics: []libcommon.Hash{libcommon.HexToHash("dead"), libcommon.HexToHash("beef")},
Data: []byte{0x01, 0x00, 0xff},
},
{
Address: libcommon.BytesToAddress([]byte{0x01, 0x11}),
Topics: []libcommon.Hash{libcommon.HexToHash("dead"), libcommon.HexToHash("beef")},
Data: []byte{0x01, 0x00, 0xff},
},
},
Type: DynamicFeeTxType,
}

t.Run("MarshalBinary", func(t *testing.T) {
// Legacy Receipt
legacyReceipt.Bloom = CreateBloom(Receipts{legacyReceipt})
have, err := legacyReceipt.MarshalBinary()
if err != nil {
t.Fatalf("marshal binary error: %v", err)
}
legacyReceipts := Receipts{legacyReceipt}
buf := new(bytes.Buffer)
legacyReceipts.EncodeIndex(0, buf)
haveEncodeIndex := buf.Bytes()
if !bytes.Equal(have, haveEncodeIndex) {
t.Errorf("BinaryMarshal and EncodeIndex mismatch, got %x want %x", have, haveEncodeIndex)
}
buf.Reset()
if err := legacyReceipt.EncodeRLP(buf); err != nil {
t.Fatalf("encode rlp error: %v", err)
}
haveRLPEncode := buf.Bytes()
if !bytes.Equal(have, haveRLPEncode) {
t.Errorf("BinaryMarshal and EncodeRLP mismatch for legacy tx, got %x want %x", have, haveRLPEncode)
}
legacyWant := libcommon.FromHex("f901c58001b9010000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000000000000000010000080000000000000000000004000000000000000000000000000040000000000000000000000000000800000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000f8bef85d940000000000000000000000000000000000000011f842a0000000000000000000000000000000000000000000000000000000000000deada0000000000000000000000000000000000000000000000000000000000000beef830100fff85d940000000000000000000000000000000000000111f842a0000000000000000000000000000000000000000000000000000000000000deada0000000000000000000000000000000000000000000000000000000000000beef830100ff")
if !bytes.Equal(have, legacyWant) {
t.Errorf("encoded RLP mismatch, got %x want %x", have, legacyWant)
}

// 2930 Receipt
buf.Reset()
accessListReceipt.Bloom = CreateBloom(Receipts{accessListReceipt})
have, err = accessListReceipt.MarshalBinary()
if err != nil {
t.Fatalf("marshal binary error: %v", err)
}
accessListReceipts := Receipts{accessListReceipt}
accessListReceipts.EncodeIndex(0, buf)
haveEncodeIndex = buf.Bytes()
if !bytes.Equal(have, haveEncodeIndex) {
t.Errorf("BinaryMarshal and EncodeIndex mismatch, got %x want %x", have, haveEncodeIndex)
}
accessListWant := libcommon.FromHex("01f901c58001b9010000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000000000000000010000080000000000000000000004000000000000000000000000000040000000000000000000000000000800000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000f8bef85d940000000000000000000000000000000000000011f842a0000000000000000000000000000000000000000000000000000000000000deada0000000000000000000000000000000000000000000000000000000000000beef830100fff85d940000000000000000000000000000000000000111f842a0000000000000000000000000000000000000000000000000000000000000deada0000000000000000000000000000000000000000000000000000000000000beef830100ff")
if !bytes.Equal(have, accessListWant) {
t.Errorf("encoded RLP mismatch, got %x want %x", have, accessListWant)
}

// 1559 Receipt
buf.Reset()
eip1559Receipt.Bloom = CreateBloom(Receipts{eip1559Receipt})
have, err = eip1559Receipt.MarshalBinary()
if err != nil {
t.Fatalf("marshal binary error: %v", err)
}
eip1559Receipts := Receipts{eip1559Receipt}
eip1559Receipts.EncodeIndex(0, buf)
haveEncodeIndex = buf.Bytes()
if !bytes.Equal(have, haveEncodeIndex) {
t.Errorf("BinaryMarshal and EncodeIndex mismatch, got %x want %x", have, haveEncodeIndex)
}
eip1559Want := libcommon.FromHex("02f901c58001b9010000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000000000000000010000080000000000000000000004000000000000000000000000000040000000000000000000000000000800000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000f8bef85d940000000000000000000000000000000000000011f842a0000000000000000000000000000000000000000000000000000000000000deada0000000000000000000000000000000000000000000000000000000000000beef830100fff85d940000000000000000000000000000000000000111f842a0000000000000000000000000000000000000000000000000000000000000deada0000000000000000000000000000000000000000000000000000000000000beef830100ff")
if !bytes.Equal(have, eip1559Want) {
t.Errorf("encoded RLP mismatch, got %x want %x", have, eip1559Want)
}
})

t.Run("UnmarshalBinary", func(t *testing.T) {
// Legacy Receipt
legacyBinary := libcommon.FromHex("f901c58001b9010000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000000000000000010000080000000000000000000004000000000000000000000000000040000000000000000000000000000800000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000f8bef85d940000000000000000000000000000000000000011f842a0000000000000000000000000000000000000000000000000000000000000deada0000000000000000000000000000000000000000000000000000000000000beef830100fff85d940000000000000000000000000000000000000111f842a0000000000000000000000000000000000000000000000000000000000000deada0000000000000000000000000000000000000000000000000000000000000beef830100ff")
gotLegacyReceipt := new(Receipt)
if err := gotLegacyReceipt.UnmarshalBinary(legacyBinary); err != nil {
t.Fatalf("unmarshal binary error: %v", err)
}
legacyReceipt.Bloom = CreateBloom(Receipts{legacyReceipt})
if !reflect.DeepEqual(gotLegacyReceipt, legacyReceipt) {
t.Errorf("receipt unmarshalled from binary mismatch, got %v want %v", gotLegacyReceipt, legacyReceipt)
}

// 2930 Receipt
accessListBinary := libcommon.FromHex("01f901c58001b9010000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000000000000000010000080000000000000000000004000000000000000000000000000040000000000000000000000000000800000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000f8bef85d940000000000000000000000000000000000000011f842a0000000000000000000000000000000000000000000000000000000000000deada0000000000000000000000000000000000000000000000000000000000000beef830100fff85d940000000000000000000000000000000000000111f842a0000000000000000000000000000000000000000000000000000000000000deada0000000000000000000000000000000000000000000000000000000000000beef830100ff")
gotAccessListReceipt := new(Receipt)
if err := gotAccessListReceipt.UnmarshalBinary(accessListBinary); err != nil {
t.Fatalf("unmarshal binary error: %v", err)
}
accessListReceipt.Bloom = CreateBloom(Receipts{accessListReceipt})
if !reflect.DeepEqual(gotAccessListReceipt, accessListReceipt) {
t.Errorf("receipt unmarshalled from binary mismatch, got %v want %v", gotAccessListReceipt, accessListReceipt)
}

// 1559 Receipt
eip1559RctBinary := libcommon.FromHex("02f901c58001b9010000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000000000000000010000080000000000000000000004000000000000000000000000000040000000000000000000000000000800000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000f8bef85d940000000000000000000000000000000000000011f842a0000000000000000000000000000000000000000000000000000000000000deada0000000000000000000000000000000000000000000000000000000000000beef830100fff85d940000000000000000000000000000000000000111f842a0000000000000000000000000000000000000000000000000000000000000deada0000000000000000000000000000000000000000000000000000000000000beef830100ff")
got1559Receipt := new(Receipt)
if err := got1559Receipt.UnmarshalBinary(eip1559RctBinary); err != nil {
t.Fatalf("unmarshal binary error: %v", err)
}
eip1559Receipt.Bloom = CreateBloom(Receipts{eip1559Receipt})
if !reflect.DeepEqual(got1559Receipt, eip1559Receipt) {
t.Errorf("receipt unmarshalled from binary mismatch, got %v want %v", got1559Receipt, eip1559Receipt)
}
})
}
53 changes: 53 additions & 0 deletions turbo/jsonrpc/debug_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ type PrivateDebugAPI interface {
AccountAt(ctx context.Context, blockHash common.Hash, txIndex uint64, account common.Address) (*AccountResult, error)
GetRawHeader(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (hexutility.Bytes, error)
GetRawBlock(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (hexutility.Bytes, error)
GetRawReceipts(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) ([]hexutility.Bytes, error)
}

// PrivateDebugAPIImpl is implementation of the PrivateDebugAPI interface based on remote Db access
Expand Down Expand Up @@ -393,3 +394,55 @@ func (api *PrivateDebugAPIImpl) GetRawBlock(ctx context.Context, blockNrOrHash r
}
return rlp.EncodeToBytes(block)
}

// GetRawReceipts retrieves the binary-encoded receipts of a single block.
func (api *PrivateDebugAPIImpl) GetRawReceipts(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) ([]hexutility.Bytes, error) {
tx, err := api.db.BeginRo(ctx)
if err != nil {
return nil, err
}
defer tx.Rollback()

blockNum, blockHash, _, err := rpchelper.GetBlockNumber(ctx, blockNrOrHash, tx, api._blockReader, api.filters)
if err != nil {
return nil, err
}
block, err := api.blockWithSenders(ctx, tx, blockHash, blockNum)
if err != nil {
return nil, err
}
if block == nil {
return nil, nil
}
receipts, err := api.getReceipts(ctx, tx, block)

Check failure on line 417 in turbo/jsonrpc/debug_api.go

View workflow job for this annotation

GitHub Actions / lint

cannot use tx (variable of type kv.Tx) as kv.TemporalTx value in argument to api.getReceipts: kv.Tx does not implement kv.TemporalTx (missing method GetAsOf)

Check failure on line 417 in turbo/jsonrpc/debug_api.go

View workflow job for this annotation

GitHub Actions / lint

cannot use tx (variable of type kv.Tx) as kv.TemporalTx value in argument to api.getReceipts: kv.Tx does not implement kv.TemporalTx (missing method GetAsOf)

Check failure on line 417 in turbo/jsonrpc/debug_api.go

View workflow job for this annotation

GitHub Actions / tests-mac-linux (ubuntu-22.04)

cannot use tx (variable of type kv.Tx) as kv.TemporalTx value in argument to api.getReceipts: kv.Tx does not implement kv.TemporalTx (missing method GetAsOf)

Check failure on line 417 in turbo/jsonrpc/debug_api.go

View workflow job for this annotation

GitHub Actions / tests-mac-linux (macos-14)

cannot use tx (variable of type kv.Tx) as kv.TemporalTx value in argument to api.getReceipts: kv.Tx does not implement kv.TemporalTx (missing method GetAsOf)

Check failure on line 417 in turbo/jsonrpc/debug_api.go

View workflow job for this annotation

GitHub Actions / tests-mac-linux (ubuntu-latest-erigontests-large)

cannot use tx (variable of type kv.Tx) as kv.TemporalTx value in argument to api.getReceipts: kv.Tx does not implement kv.TemporalTx (missing method GetAsOf)

Check failure on line 417 in turbo/jsonrpc/debug_api.go

View workflow job for this annotation

GitHub Actions / tests-windows (windows-2022)

cannot use tx (variable of type kv.Tx) as kv.TemporalTx value in argument to api.getReceipts: kv.Tx does not implement kv.TemporalTx (missing method GetAsOf)

Check failure on line 417 in turbo/jsonrpc/debug_api.go

View workflow job for this annotation

GitHub Actions / tests-windows (windows-2022)

cannot use tx (variable of type kv.Tx) as kv.TemporalTx value in argument to api.getReceipts: kv.Tx does not implement kv.TemporalTx (missing method GetAsOf)
if err != nil {
return nil, fmt.Errorf("getReceipts error: %w", err)
}
chainConfig, err := api.chainConfig(ctx, tx)
if err != nil {
return nil, err
}
if chainConfig.Bor != nil {
events, err := api.stateSyncEvents(ctx, tx, block.Hash(), blockNum, chainConfig)
if err != nil {
return nil, err
}
if len(events) != 0 {
borReceipt, err := api.borReceiptGenerator.GenerateBorReceipt(ctx, tx, block, events, chainConfig, receipts)

Check failure on line 431 in turbo/jsonrpc/debug_api.go

View workflow job for this annotation

GitHub Actions / lint

cannot use tx (variable of type kv.Tx) as kv.TemporalTx value in argument to api.borReceiptGenerator.GenerateBorReceipt: kv.Tx does not implement kv.TemporalTx (missing method GetAsOf)) (typecheck)

Check failure on line 431 in turbo/jsonrpc/debug_api.go

View workflow job for this annotation

GitHub Actions / lint

cannot use tx (variable of type kv.Tx) as kv.TemporalTx value in argument to api.borReceiptGenerator.GenerateBorReceipt: kv.Tx does not implement kv.TemporalTx (missing method GetAsOf)) (typecheck)

Check failure on line 431 in turbo/jsonrpc/debug_api.go

View workflow job for this annotation

GitHub Actions / tests-mac-linux (ubuntu-22.04)

cannot use tx (variable of type kv.Tx) as kv.TemporalTx value in argument to api.borReceiptGenerator.GenerateBorReceipt: kv.Tx does not implement kv.TemporalTx (missing method GetAsOf)

Check failure on line 431 in turbo/jsonrpc/debug_api.go

View workflow job for this annotation

GitHub Actions / tests-mac-linux (macos-14)

cannot use tx (variable of type kv.Tx) as kv.TemporalTx value in argument to api.borReceiptGenerator.GenerateBorReceipt: kv.Tx does not implement kv.TemporalTx (missing method GetAsOf)

Check failure on line 431 in turbo/jsonrpc/debug_api.go

View workflow job for this annotation

GitHub Actions / tests-mac-linux (ubuntu-latest-erigontests-large)

cannot use tx (variable of type kv.Tx) as kv.TemporalTx value in argument to api.borReceiptGenerator.GenerateBorReceipt: kv.Tx does not implement kv.TemporalTx (missing method GetAsOf)

Check failure on line 431 in turbo/jsonrpc/debug_api.go

View workflow job for this annotation

GitHub Actions / tests-windows (windows-2022)

cannot use tx (variable of type kv.Tx) as kv.TemporalTx value in argument to api.borReceiptGenerator.GenerateBorReceipt: kv.Tx does not implement kv.TemporalTx (missing method GetAsOf)

Check failure on line 431 in turbo/jsonrpc/debug_api.go

View workflow job for this annotation

GitHub Actions / tests-windows (windows-2022)

cannot use tx (variable of type kv.Tx) as kv.TemporalTx value in argument to api.borReceiptGenerator.GenerateBorReceipt: kv.Tx does not implement kv.TemporalTx (missing method GetAsOf)
if err != nil {
return nil, err
}
receipts = append(receipts, borReceipt)
}
}

result := make([]hexutility.Bytes, len(receipts))
for i, receipt := range receipts {
b, err := receipt.MarshalBinary()
if err != nil {
return nil, err
}
result[i] = b
}
return result, nil
}
8 changes: 2 additions & 6 deletions turbo/jsonrpc/erigon_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,11 @@ package jsonrpc
import (
"context"

"github.com/erigontech/erigon-lib/common/hexutil"

"github.com/erigontech/erigon-lib/common"

"github.com/erigontech/erigon/eth/filters"

"github.com/erigontech/erigon-lib/common/hexutil"
"github.com/erigontech/erigon-lib/kv"

"github.com/erigontech/erigon/core/types"
"github.com/erigontech/erigon/eth/filters"
"github.com/erigontech/erigon/p2p"
"github.com/erigontech/erigon/rpc"
"github.com/erigontech/erigon/turbo/rpchelper"
Expand Down

0 comments on commit 2b6da7a

Please sign in to comment.