mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-01-10 07:58:22 -05:00
Major Simplification of JSON Handling for Execution Blocks (#10993)
* no more execution block custom type * simpler json rpc data unmarshaling * simplicify * included hash and txs fix * all tests * pass * build * mock fix * attempt build * builds * build * builds * pass * pass * build Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
This commit is contained in:
@@ -6,6 +6,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
gethtypes "github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/cache"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
|
||||
testDB "github.com/prysmaticlabs/prysm/beacon-chain/db/testing"
|
||||
@@ -698,11 +699,15 @@ func Test_NotifyNewPayload(t *testing.T) {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
e := &mockPOW.EngineClient{ErrNewPayload: tt.newPayloadErr, BlockByHashMap: map[[32]byte]*v1.ExecutionBlock{}}
|
||||
e.BlockByHashMap[[32]byte{'a'}] = &v1.ExecutionBlock{
|
||||
ParentHash: bytesutil.PadTo([]byte{'b'}, fieldparams.RootLength),
|
||||
Header: gethtypes.Header{
|
||||
ParentHash: common.BytesToHash([]byte("b")),
|
||||
},
|
||||
TotalDifficulty: "0x2",
|
||||
}
|
||||
e.BlockByHashMap[[32]byte{'b'}] = &v1.ExecutionBlock{
|
||||
ParentHash: bytesutil.PadTo([]byte{'3'}, fieldparams.RootLength),
|
||||
Header: gethtypes.Header{
|
||||
ParentHash: common.BytesToHash([]byte("3")),
|
||||
},
|
||||
TotalDifficulty: "0x1",
|
||||
}
|
||||
service.cfg.ExecutionEngineCaller = e
|
||||
@@ -755,11 +760,15 @@ func Test_NotifyNewPayload_SetOptimisticToValid(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
e := &mockPOW.EngineClient{BlockByHashMap: map[[32]byte]*v1.ExecutionBlock{}}
|
||||
e.BlockByHashMap[[32]byte{'a'}] = &v1.ExecutionBlock{
|
||||
ParentHash: bytesutil.PadTo([]byte{'b'}, fieldparams.RootLength),
|
||||
Header: gethtypes.Header{
|
||||
ParentHash: common.BytesToHash([]byte("b")),
|
||||
},
|
||||
TotalDifficulty: "0x2",
|
||||
}
|
||||
e.BlockByHashMap[[32]byte{'b'}] = &v1.ExecutionBlock{
|
||||
ParentHash: bytesutil.PadTo([]byte{'3'}, fieldparams.RootLength),
|
||||
Header: gethtypes.Header{
|
||||
ParentHash: common.BytesToHash([]byte("3")),
|
||||
},
|
||||
TotalDifficulty: "0x1",
|
||||
}
|
||||
service.cfg.ExecutionEngineCaller = e
|
||||
|
||||
@@ -100,7 +100,7 @@ func (s *Service) getBlkParentHashAndTD(ctx context.Context, blkHash []byte) ([]
|
||||
if overflows {
|
||||
return nil, nil, errors.New("total difficulty overflows")
|
||||
}
|
||||
return blk.ParentHash, blkTDUint256, nil
|
||||
return blk.ParentHash[:], blkTDUint256, nil
|
||||
}
|
||||
|
||||
// validateTerminalBlockHash validates if the merge block is a valid terminal PoW block.
|
||||
|
||||
@@ -6,12 +6,12 @@ import (
|
||||
"math/big"
|
||||
"testing"
|
||||
|
||||
gethtypes "github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/holiman/uint256"
|
||||
testDB "github.com/prysmaticlabs/prysm/beacon-chain/db/testing"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/forkchoice/protoarray"
|
||||
mocks "github.com/prysmaticlabs/prysm/beacon-chain/powchain/testing"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/state/stategen"
|
||||
fieldparams "github.com/prysmaticlabs/prysm/config/fieldparams"
|
||||
"github.com/prysmaticlabs/prysm/config/params"
|
||||
"github.com/prysmaticlabs/prysm/consensus-types/wrapper"
|
||||
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
||||
@@ -120,12 +120,19 @@ func Test_validateMergeBlock(t *testing.T) {
|
||||
|
||||
engine := &mocks.EngineClient{BlockByHashMap: map[[32]byte]*enginev1.ExecutionBlock{}}
|
||||
service.cfg.ExecutionEngineCaller = engine
|
||||
engine.BlockByHashMap[[32]byte{'a'}] = &enginev1.ExecutionBlock{
|
||||
ParentHash: bytesutil.PadTo([]byte{'b'}, fieldparams.RootLength),
|
||||
a := [32]byte{'a'}
|
||||
b := [32]byte{'b'}
|
||||
mergeBlockParentHash := [32]byte{'3'}
|
||||
engine.BlockByHashMap[a] = &enginev1.ExecutionBlock{
|
||||
Header: gethtypes.Header{
|
||||
ParentHash: b,
|
||||
},
|
||||
TotalDifficulty: "0x2",
|
||||
}
|
||||
engine.BlockByHashMap[[32]byte{'b'}] = &enginev1.ExecutionBlock{
|
||||
ParentHash: bytesutil.PadTo([]byte{'3'}, fieldparams.RootLength),
|
||||
engine.BlockByHashMap[b] = &enginev1.ExecutionBlock{
|
||||
Header: gethtypes.Header{
|
||||
ParentHash: mergeBlockParentHash,
|
||||
},
|
||||
TotalDifficulty: "0x1",
|
||||
}
|
||||
blk := ðpb.SignedBeaconBlockBellatrix{
|
||||
@@ -133,18 +140,18 @@ func Test_validateMergeBlock(t *testing.T) {
|
||||
Slot: 1,
|
||||
Body: ðpb.BeaconBlockBodyBellatrix{
|
||||
ExecutionPayload: &enginev1.ExecutionPayload{
|
||||
ParentHash: bytesutil.PadTo([]byte{'a'}, fieldparams.RootLength),
|
||||
ParentHash: a[:],
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
b, err := wrapper.WrappedSignedBeaconBlock(blk)
|
||||
bk, err := wrapper.WrappedSignedBeaconBlock(blk)
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, service.validateMergeBlock(ctx, b))
|
||||
require.NoError(t, service.validateMergeBlock(ctx, bk))
|
||||
|
||||
cfg.TerminalTotalDifficulty = "1"
|
||||
params.OverrideBeaconConfig(cfg)
|
||||
err = service.validateMergeBlock(ctx, b)
|
||||
err = service.validateMergeBlock(ctx, bk)
|
||||
require.ErrorContains(t, "invalid TTD, configTTD: 1, currentTTD: 2, parentTTD: 1", err)
|
||||
require.Equal(t, true, IsInvalidBlock(err))
|
||||
}
|
||||
@@ -167,7 +174,9 @@ func Test_getBlkParentHashAndTD(t *testing.T) {
|
||||
p := [32]byte{'b'}
|
||||
td := "0x1"
|
||||
engine.BlockByHashMap[h] = &enginev1.ExecutionBlock{
|
||||
ParentHash: p[:],
|
||||
Header: gethtypes.Header{
|
||||
ParentHash: p,
|
||||
},
|
||||
TotalDifficulty: td,
|
||||
}
|
||||
parentHash, totalDifficulty, err := service.getBlkParentHashAndTD(ctx, h[:])
|
||||
@@ -183,14 +192,18 @@ func Test_getBlkParentHashAndTD(t *testing.T) {
|
||||
require.ErrorContains(t, "pow block is nil", err)
|
||||
|
||||
engine.BlockByHashMap[h] = &enginev1.ExecutionBlock{
|
||||
ParentHash: p[:],
|
||||
Header: gethtypes.Header{
|
||||
ParentHash: p,
|
||||
},
|
||||
TotalDifficulty: "1",
|
||||
}
|
||||
_, _, err = service.getBlkParentHashAndTD(ctx, h[:])
|
||||
require.ErrorContains(t, "could not decode merge block total difficulty: hex string without 0x prefix", err)
|
||||
|
||||
engine.BlockByHashMap[h] = &enginev1.ExecutionBlock{
|
||||
ParentHash: p[:],
|
||||
Header: gethtypes.Header{
|
||||
ParentHash: p,
|
||||
},
|
||||
TotalDifficulty: "0XFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
|
||||
}
|
||||
_, _, err = service.getBlkParentHashAndTD(ctx, h[:])
|
||||
|
||||
@@ -9,6 +9,8 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
gethtypes "github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/pkg/errors"
|
||||
mock "github.com/prysmaticlabs/prysm/beacon-chain/blockchain/testing"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/cache"
|
||||
@@ -1527,6 +1529,9 @@ func Test_validateMergeTransitionBlock(t *testing.T) {
|
||||
service, err := NewService(ctx, opts...)
|
||||
require.NoError(t, err)
|
||||
|
||||
aHash := common.BytesToHash([]byte("a"))
|
||||
bHash := common.BytesToHash([]byte("b"))
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
stateVersion int
|
||||
@@ -1557,7 +1562,7 @@ func Test_validateMergeTransitionBlock(t *testing.T) {
|
||||
name: "state older than Bellatrix, non empty payload",
|
||||
stateVersion: 1,
|
||||
payload: &enginev1.ExecutionPayload{
|
||||
ParentHash: bytesutil.PadTo([]byte{'a'}, fieldparams.RootLength),
|
||||
ParentHash: aHash[:],
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -1583,7 +1588,7 @@ func Test_validateMergeTransitionBlock(t *testing.T) {
|
||||
name: "state is Bellatrix, non empty payload, empty header",
|
||||
stateVersion: 2,
|
||||
payload: &enginev1.ExecutionPayload{
|
||||
ParentHash: bytesutil.PadTo([]byte{'a'}, fieldparams.RootLength),
|
||||
ParentHash: aHash[:],
|
||||
},
|
||||
header: &enginev1.ExecutionPayloadHeader{
|
||||
ParentHash: make([]byte, fieldparams.RootLength),
|
||||
@@ -1601,7 +1606,7 @@ func Test_validateMergeTransitionBlock(t *testing.T) {
|
||||
name: "state is Bellatrix, non empty payload, non empty header",
|
||||
stateVersion: 2,
|
||||
payload: &enginev1.ExecutionPayload{
|
||||
ParentHash: bytesutil.PadTo([]byte{'a'}, fieldparams.RootLength),
|
||||
ParentHash: aHash[:],
|
||||
},
|
||||
header: &enginev1.ExecutionPayloadHeader{
|
||||
BlockNumber: 1,
|
||||
@@ -1611,7 +1616,7 @@ func Test_validateMergeTransitionBlock(t *testing.T) {
|
||||
name: "state is Bellatrix, non empty payload, nil header",
|
||||
stateVersion: 2,
|
||||
payload: &enginev1.ExecutionPayload{
|
||||
ParentHash: bytesutil.PadTo([]byte{'a'}, fieldparams.RootLength),
|
||||
ParentHash: aHash[:],
|
||||
},
|
||||
errString: "nil header or block body",
|
||||
},
|
||||
@@ -1619,12 +1624,16 @@ func Test_validateMergeTransitionBlock(t *testing.T) {
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
e := &mockPOW.EngineClient{BlockByHashMap: map[[32]byte]*enginev1.ExecutionBlock{}}
|
||||
e.BlockByHashMap[[32]byte{'a'}] = &enginev1.ExecutionBlock{
|
||||
ParentHash: bytesutil.PadTo([]byte{'b'}, fieldparams.RootLength),
|
||||
e.BlockByHashMap[aHash] = &enginev1.ExecutionBlock{
|
||||
Header: gethtypes.Header{
|
||||
ParentHash: bHash,
|
||||
},
|
||||
TotalDifficulty: "0x2",
|
||||
}
|
||||
e.BlockByHashMap[[32]byte{'b'}] = &enginev1.ExecutionBlock{
|
||||
ParentHash: bytesutil.PadTo([]byte{'3'}, fieldparams.RootLength),
|
||||
e.BlockByHashMap[bHash] = &enginev1.ExecutionBlock{
|
||||
Header: gethtypes.Header{
|
||||
ParentHash: common.BytesToHash([]byte("3")),
|
||||
},
|
||||
TotalDifficulty: "0x1",
|
||||
}
|
||||
service.cfg.ExecutionEngineCaller = e
|
||||
|
||||
@@ -4,12 +4,14 @@ import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"math/big"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
gethtypes "github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/rpc"
|
||||
"github.com/holiman/uint256"
|
||||
mockChain "github.com/prysmaticlabs/prysm/beacon-chain/blockchain/testing"
|
||||
@@ -161,7 +163,27 @@ func TestService_logTtdStatus(t *testing.T) {
|
||||
require.NoError(t, r.Body.Close())
|
||||
}()
|
||||
|
||||
resp := &pb.ExecutionBlock{TotalDifficulty: "0x12345678"}
|
||||
resp := &pb.ExecutionBlock{
|
||||
Header: gethtypes.Header{
|
||||
ParentHash: common.Hash{},
|
||||
UncleHash: common.Hash{},
|
||||
Coinbase: common.Address{},
|
||||
Root: common.Hash{},
|
||||
TxHash: common.Hash{},
|
||||
ReceiptHash: common.Hash{},
|
||||
Bloom: gethtypes.Bloom{},
|
||||
Difficulty: big.NewInt(1),
|
||||
Number: big.NewInt(2),
|
||||
GasLimit: 3,
|
||||
GasUsed: 4,
|
||||
Time: 5,
|
||||
Extra: nil,
|
||||
MixDigest: common.Hash{},
|
||||
Nonce: gethtypes.BlockNonce{},
|
||||
BaseFee: big.NewInt(6),
|
||||
},
|
||||
TotalDifficulty: "0x12345678",
|
||||
}
|
||||
respJSON := map[string]interface{}{
|
||||
"jsonrpc": "2.0",
|
||||
"id": 1,
|
||||
|
||||
@@ -228,8 +228,8 @@ func (s *Service) GetTerminalBlockHash(ctx context.Context) ([]byte, bool, error
|
||||
}
|
||||
blockReachedTTD := currentTotalDifficulty.Cmp(terminalTotalDifficulty) >= 0
|
||||
|
||||
parentHash := bytesutil.ToBytes32(blk.ParentHash)
|
||||
if len(blk.ParentHash) == 0 || parentHash == params.BeaconConfig().ZeroHash {
|
||||
parentHash := blk.ParentHash
|
||||
if parentHash == params.BeaconConfig().ZeroHash {
|
||||
return nil, false, nil
|
||||
}
|
||||
parentBlk, err := s.ExecutionBlockByHash(ctx, parentHash)
|
||||
@@ -248,12 +248,12 @@ func (s *Service) GetTerminalBlockHash(ctx context.Context) ([]byte, bool, error
|
||||
if !parentReachedTTD {
|
||||
log.WithFields(logrus.Fields{
|
||||
"number": blk.Number,
|
||||
"hash": fmt.Sprintf("%#x", bytesutil.Trunc(blk.Hash)),
|
||||
"hash": fmt.Sprintf("%#x", bytesutil.Trunc(blk.Hash[:])),
|
||||
"td": blk.TotalDifficulty,
|
||||
"parentTd": parentBlk.TotalDifficulty,
|
||||
"ttd": terminalTotalDifficulty,
|
||||
}).Info("Retrieved terminal block hash")
|
||||
return blk.Hash, true, nil
|
||||
return blk.Hash[:], true, nil
|
||||
}
|
||||
} else {
|
||||
return nil, false, nil
|
||||
|
||||
@@ -12,6 +12,7 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
gethtypes "github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/rpc"
|
||||
"github.com/holiman/uint256"
|
||||
"github.com/pkg/errors"
|
||||
@@ -416,7 +417,7 @@ func TestServer_getPowBlockHashAtTerminalTotalDifficulty(t *testing.T) {
|
||||
name: "current execution block invalid TD",
|
||||
paramsTd: "1",
|
||||
currentPowBlock: &pb.ExecutionBlock{
|
||||
Hash: []byte{'a'},
|
||||
Hash: common.BytesToHash([]byte("a")),
|
||||
TotalDifficulty: "1115792089237316195423570985008687907853269984665640564039457584007913129638912",
|
||||
},
|
||||
errString: "could not convert total difficulty to uint256",
|
||||
@@ -425,8 +426,10 @@ func TestServer_getPowBlockHashAtTerminalTotalDifficulty(t *testing.T) {
|
||||
name: "current execution block has zero hash parent",
|
||||
paramsTd: "2",
|
||||
currentPowBlock: &pb.ExecutionBlock{
|
||||
Hash: []byte{'a'},
|
||||
ParentHash: params.BeaconConfig().ZeroHash[:],
|
||||
Hash: common.BytesToHash([]byte("a")),
|
||||
Header: gethtypes.Header{
|
||||
ParentHash: common.BytesToHash(params.BeaconConfig().ZeroHash[:]),
|
||||
},
|
||||
TotalDifficulty: "0x3",
|
||||
},
|
||||
},
|
||||
@@ -434,8 +437,10 @@ func TestServer_getPowBlockHashAtTerminalTotalDifficulty(t *testing.T) {
|
||||
name: "could not get parent block",
|
||||
paramsTd: "2",
|
||||
currentPowBlock: &pb.ExecutionBlock{
|
||||
Hash: []byte{'a'},
|
||||
ParentHash: []byte{'b'},
|
||||
Hash: common.BytesToHash([]byte("a")),
|
||||
Header: gethtypes.Header{
|
||||
ParentHash: common.BytesToHash([]byte("b")),
|
||||
},
|
||||
TotalDifficulty: "0x3",
|
||||
},
|
||||
errString: "could not get parent execution block",
|
||||
@@ -444,13 +449,17 @@ func TestServer_getPowBlockHashAtTerminalTotalDifficulty(t *testing.T) {
|
||||
name: "parent execution block invalid TD",
|
||||
paramsTd: "2",
|
||||
currentPowBlock: &pb.ExecutionBlock{
|
||||
Hash: []byte{'a'},
|
||||
ParentHash: []byte{'b'},
|
||||
Hash: common.BytesToHash([]byte("a")),
|
||||
Header: gethtypes.Header{
|
||||
ParentHash: common.BytesToHash([]byte("b")),
|
||||
},
|
||||
TotalDifficulty: "0x3",
|
||||
},
|
||||
parentPowBlock: &pb.ExecutionBlock{
|
||||
Hash: []byte{'b'},
|
||||
ParentHash: []byte{'c'},
|
||||
Hash: common.BytesToHash([]byte("b")),
|
||||
Header: gethtypes.Header{
|
||||
ParentHash: common.BytesToHash([]byte("c")),
|
||||
},
|
||||
TotalDifficulty: "1",
|
||||
},
|
||||
errString: "could not convert total difficulty to uint256",
|
||||
@@ -459,29 +468,37 @@ func TestServer_getPowBlockHashAtTerminalTotalDifficulty(t *testing.T) {
|
||||
name: "happy case",
|
||||
paramsTd: "2",
|
||||
currentPowBlock: &pb.ExecutionBlock{
|
||||
Hash: []byte{'a'},
|
||||
ParentHash: []byte{'b'},
|
||||
Hash: common.BytesToHash([]byte("a")),
|
||||
Header: gethtypes.Header{
|
||||
ParentHash: common.BytesToHash([]byte("b")),
|
||||
},
|
||||
TotalDifficulty: "0x3",
|
||||
},
|
||||
parentPowBlock: &pb.ExecutionBlock{
|
||||
Hash: []byte{'b'},
|
||||
ParentHash: []byte{'c'},
|
||||
Hash: common.BytesToHash([]byte("b")),
|
||||
Header: gethtypes.Header{
|
||||
ParentHash: common.BytesToHash([]byte("c")),
|
||||
},
|
||||
TotalDifficulty: "0x1",
|
||||
},
|
||||
wantExists: true,
|
||||
wantTerminalBlockHash: []byte{'a'},
|
||||
wantTerminalBlockHash: common.BytesToHash([]byte("a")).Bytes(),
|
||||
},
|
||||
{
|
||||
name: "ttd not reached",
|
||||
paramsTd: "3",
|
||||
currentPowBlock: &pb.ExecutionBlock{
|
||||
Hash: []byte{'a'},
|
||||
ParentHash: []byte{'b'},
|
||||
Hash: common.BytesToHash([]byte("a")),
|
||||
Header: gethtypes.Header{
|
||||
ParentHash: common.BytesToHash([]byte("b")),
|
||||
},
|
||||
TotalDifficulty: "0x2",
|
||||
},
|
||||
parentPowBlock: &pb.ExecutionBlock{
|
||||
Hash: []byte{'b'},
|
||||
ParentHash: []byte{'c'},
|
||||
Hash: common.BytesToHash([]byte("b")),
|
||||
Header: gethtypes.Header{
|
||||
ParentHash: common.BytesToHash([]byte("c")),
|
||||
},
|
||||
TotalDifficulty: "0x1",
|
||||
},
|
||||
},
|
||||
@@ -494,7 +511,7 @@ func TestServer_getPowBlockHashAtTerminalTotalDifficulty(t *testing.T) {
|
||||
var m map[[32]byte]*pb.ExecutionBlock
|
||||
if tt.parentPowBlock != nil {
|
||||
m = map[[32]byte]*pb.ExecutionBlock{
|
||||
bytesutil.ToBytes32(tt.parentPowBlock.Hash): tt.parentPowBlock,
|
||||
tt.parentPowBlock.Hash: tt.parentPowBlock,
|
||||
}
|
||||
}
|
||||
client := mocks.EngineClient{
|
||||
@@ -749,8 +766,6 @@ func fixtures() map[string]interface{} {
|
||||
BlockHash: foo[:],
|
||||
Transactions: [][]byte{foo[:]},
|
||||
}
|
||||
number := bytesutil.PadTo([]byte("100"), fieldparams.RootLength)
|
||||
hash := bytesutil.PadTo([]byte("hash"), fieldparams.RootLength)
|
||||
parent := bytesutil.PadTo([]byte("parentHash"), fieldparams.RootLength)
|
||||
sha3Uncles := bytesutil.PadTo([]byte("sha3Uncles"), fieldparams.RootLength)
|
||||
miner := bytesutil.PadTo([]byte("miner"), fieldparams.FeeRecipientLength)
|
||||
@@ -759,25 +774,24 @@ func fixtures() map[string]interface{} {
|
||||
receiptsRoot := bytesutil.PadTo([]byte("receiptsRoot"), fieldparams.RootLength)
|
||||
logsBloom := bytesutil.PadTo([]byte("logs"), fieldparams.LogsBloomLength)
|
||||
executionBlock := &pb.ExecutionBlock{
|
||||
Number: number,
|
||||
Hash: hash,
|
||||
ParentHash: parent,
|
||||
Sha3Uncles: sha3Uncles,
|
||||
Miner: miner,
|
||||
StateRoot: stateRoot,
|
||||
TransactionsRoot: transactionsRoot,
|
||||
ReceiptsRoot: receiptsRoot,
|
||||
LogsBloom: logsBloom,
|
||||
Difficulty: bytesutil.PadTo([]byte("1"), fieldparams.RootLength),
|
||||
TotalDifficulty: "2",
|
||||
GasLimit: 3,
|
||||
GasUsed: 4,
|
||||
Timestamp: 5,
|
||||
Size: bytesutil.PadTo([]byte("6"), fieldparams.RootLength),
|
||||
ExtraData: bytesutil.PadTo([]byte("extraData"), fieldparams.RootLength),
|
||||
BaseFeePerGas: bytesutil.PadTo([]byte("baseFeePerGas"), fieldparams.RootLength),
|
||||
Transactions: [][]byte{foo[:]},
|
||||
Uncles: [][]byte{foo[:]},
|
||||
Header: gethtypes.Header{
|
||||
ParentHash: common.BytesToHash(parent),
|
||||
UncleHash: common.BytesToHash(sha3Uncles),
|
||||
Coinbase: common.BytesToAddress(miner),
|
||||
Root: common.BytesToHash(stateRoot),
|
||||
TxHash: common.BytesToHash(transactionsRoot),
|
||||
ReceiptHash: common.BytesToHash(receiptsRoot),
|
||||
Bloom: gethtypes.BytesToBloom(logsBloom),
|
||||
Difficulty: big.NewInt(1),
|
||||
Number: big.NewInt(2),
|
||||
GasLimit: 3,
|
||||
GasUsed: 4,
|
||||
Time: 5,
|
||||
Extra: []byte("extra"),
|
||||
MixDigest: common.BytesToHash([]byte("mix")),
|
||||
Nonce: gethtypes.EncodeNonce(6),
|
||||
BaseFee: big.NewInt(7),
|
||||
},
|
||||
}
|
||||
status := &pb.PayloadStatus{
|
||||
Status: pb.PayloadStatus_VALID,
|
||||
|
||||
@@ -94,8 +94,8 @@ func (e *EngineClient) GetTerminalBlockHash(ctx context.Context) ([]byte, bool,
|
||||
currentTotalDifficulty, _ := uint256.FromBig(b)
|
||||
blockReachedTTD := currentTotalDifficulty.Cmp(terminalTotalDifficulty) >= 0
|
||||
|
||||
parentHash := bytesutil.ToBytes32(blk.ParentHash)
|
||||
if len(blk.ParentHash) == 0 || parentHash == params.BeaconConfig().ZeroHash {
|
||||
parentHash := blk.ParentHash
|
||||
if parentHash == params.BeaconConfig().ZeroHash {
|
||||
return nil, false, nil
|
||||
}
|
||||
parentBlk, err := e.ExecutionBlockByHash(ctx, parentHash)
|
||||
@@ -110,7 +110,7 @@ func (e *EngineClient) GetTerminalBlockHash(ctx context.Context) ([]byte, bool,
|
||||
parentTotalDifficulty, _ := uint256.FromBig(b)
|
||||
parentReachedTTD := parentTotalDifficulty.Cmp(terminalTotalDifficulty) >= 0
|
||||
if !parentReachedTTD {
|
||||
return blk.Hash, true, nil
|
||||
return blk.Hash[:], true, nil
|
||||
}
|
||||
} else {
|
||||
return nil, false, nil
|
||||
|
||||
@@ -165,6 +165,7 @@ go_test(
|
||||
"//time/slots:go_default_library",
|
||||
"@com_github_d4l3k_messagediff//:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//common:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//core/types:go_default_library",
|
||||
"@com_github_golang_mock//gomock:go_default_library",
|
||||
"@com_github_pkg_errors//:go_default_library",
|
||||
"@com_github_prysmaticlabs_go_bitfield//:go_default_library",
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
gethtypes "github.com/ethereum/go-ethereum/core/types"
|
||||
chainMock "github.com/prysmaticlabs/prysm/beacon-chain/blockchain/testing"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/cache"
|
||||
dbTest "github.com/prysmaticlabs/prysm/beacon-chain/db/testing"
|
||||
@@ -203,7 +204,7 @@ func TestServer_getTerminalBlockHashIfExists(t *testing.T) {
|
||||
}{
|
||||
{
|
||||
name: "use terminal block hash, doesn't exist",
|
||||
paramsTerminalHash: []byte{'a'},
|
||||
paramsTerminalHash: common.BytesToHash([]byte("a")).Bytes(),
|
||||
errString: "could not fetch height for hash",
|
||||
},
|
||||
{
|
||||
@@ -218,17 +219,21 @@ func TestServer_getTerminalBlockHashIfExists(t *testing.T) {
|
||||
name: "use terminal total difficulty",
|
||||
paramsTd: "2",
|
||||
currentPowBlock: &pb.ExecutionBlock{
|
||||
Hash: []byte{'a'},
|
||||
ParentHash: []byte{'b'},
|
||||
Hash: common.BytesToHash([]byte("a")),
|
||||
Header: gethtypes.Header{
|
||||
ParentHash: common.BytesToHash([]byte("b")),
|
||||
},
|
||||
TotalDifficulty: "0x3",
|
||||
},
|
||||
parentPowBlock: &pb.ExecutionBlock{
|
||||
Hash: []byte{'b'},
|
||||
ParentHash: []byte{'c'},
|
||||
Hash: common.BytesToHash([]byte("b")),
|
||||
Header: gethtypes.Header{
|
||||
ParentHash: common.BytesToHash([]byte("c")),
|
||||
},
|
||||
TotalDifficulty: "0x1",
|
||||
},
|
||||
wantExists: true,
|
||||
wantTerminalBlockHash: []byte{'a'},
|
||||
wantTerminalBlockHash: common.BytesToHash([]byte("a")).Bytes(),
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
@@ -240,7 +245,7 @@ func TestServer_getTerminalBlockHashIfExists(t *testing.T) {
|
||||
var m map[[32]byte]*pb.ExecutionBlock
|
||||
if tt.parentPowBlock != nil {
|
||||
m = map[[32]byte]*pb.ExecutionBlock{
|
||||
bytesutil.ToBytes32(tt.parentPowBlock.Hash): tt.parentPowBlock,
|
||||
tt.parentPowBlock.Hash: tt.parentPowBlock,
|
||||
}
|
||||
}
|
||||
c := powtesting.NewPOWChain()
|
||||
|
||||
@@ -72,14 +72,15 @@ go_library(
|
||||
"//config/params:go_default_library",
|
||||
"//encoding/bytesutil:go_default_library",
|
||||
"//proto/eth/ext:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//common:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//common/hexutil:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//common:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//core/types:go_default_library",
|
||||
"@io_bazel_rules_go//proto/wkt:timestamp_go_proto",
|
||||
"@go_googleapis//google/api:annotations_go_proto",
|
||||
"@com_github_golang_protobuf//proto:go_default_library",
|
||||
"@com_github_pkg_errors//:go_default_library",
|
||||
"@com_github_prysmaticlabs_fastssz//:go_default_library",
|
||||
"@go_googleapis//google/api:annotations_go_proto",
|
||||
"@io_bazel_rules_go//proto/wkt:descriptor_go_proto",
|
||||
"@io_bazel_rules_go//proto/wkt:timestamp_go_proto",
|
||||
"@org_golang_google_protobuf//encoding/protojson:go_default_library",
|
||||
"@org_golang_google_protobuf//reflect/protoreflect:go_default_library",
|
||||
"@org_golang_google_protobuf//runtime/protoimpl:go_default_library",
|
||||
@@ -98,5 +99,7 @@ go_test(
|
||||
"//encoding/bytesutil:go_default_library",
|
||||
"//testing/require:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//common/hexutil:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//common:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//core/types:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
229
proto/engine/v1/execution_engine.pb.go
generated
229
proto/engine/v1/execution_engine.pb.go
generated
@@ -80,213 +80,6 @@ func (PayloadStatus_Status) EnumDescriptor() ([]byte, []int) {
|
||||
return file_proto_engine_v1_execution_engine_proto_rawDescGZIP(), []int{5, 0}
|
||||
}
|
||||
|
||||
type ExecutionBlock struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Number []byte `protobuf:"bytes,1,opt,name=number,proto3" json:"number,omitempty"`
|
||||
Hash []byte `protobuf:"bytes,2,opt,name=hash,proto3" json:"hash,omitempty"`
|
||||
ParentHash []byte `protobuf:"bytes,3,opt,name=parent_hash,json=parentHash,proto3" json:"parent_hash,omitempty"`
|
||||
Sha3Uncles []byte `protobuf:"bytes,4,opt,name=sha3_uncles,json=sha3Uncles,proto3" json:"sha3_uncles,omitempty"`
|
||||
Miner []byte `protobuf:"bytes,5,opt,name=miner,proto3" json:"miner,omitempty"`
|
||||
StateRoot []byte `protobuf:"bytes,6,opt,name=state_root,json=stateRoot,proto3" json:"state_root,omitempty"`
|
||||
TransactionsRoot []byte `protobuf:"bytes,7,opt,name=transactions_root,json=transactionsRoot,proto3" json:"transactions_root,omitempty"`
|
||||
ReceiptsRoot []byte `protobuf:"bytes,8,opt,name=receipts_root,json=receiptsRoot,proto3" json:"receipts_root,omitempty"`
|
||||
LogsBloom []byte `protobuf:"bytes,9,opt,name=logs_bloom,json=logsBloom,proto3" json:"logs_bloom,omitempty"`
|
||||
Difficulty []byte `protobuf:"bytes,10,opt,name=difficulty,proto3" json:"difficulty,omitempty"`
|
||||
TotalDifficulty string `protobuf:"bytes,11,opt,name=total_difficulty,json=totalDifficulty,proto3" json:"total_difficulty,omitempty"`
|
||||
GasLimit uint64 `protobuf:"varint,12,opt,name=gas_limit,json=gasLimit,proto3" json:"gas_limit,omitempty"`
|
||||
GasUsed uint64 `protobuf:"varint,13,opt,name=gas_used,json=gasUsed,proto3" json:"gas_used,omitempty"`
|
||||
BaseFeePerGas []byte `protobuf:"bytes,14,opt,name=base_fee_per_gas,json=baseFeePerGas,proto3" json:"base_fee_per_gas,omitempty"`
|
||||
Size []byte `protobuf:"bytes,15,opt,name=size,proto3" json:"size,omitempty"`
|
||||
Timestamp uint64 `protobuf:"varint,16,opt,name=timestamp,proto3" json:"timestamp,omitempty"`
|
||||
ExtraData []byte `protobuf:"bytes,17,opt,name=extra_data,json=extraData,proto3" json:"extra_data,omitempty"`
|
||||
MixHash []byte `protobuf:"bytes,18,opt,name=mix_hash,json=mixHash,proto3" json:"mix_hash,omitempty"`
|
||||
Nonce []byte `protobuf:"bytes,19,opt,name=nonce,proto3" json:"nonce,omitempty"`
|
||||
Transactions [][]byte `protobuf:"bytes,20,rep,name=transactions,proto3" json:"transactions,omitempty"`
|
||||
Uncles [][]byte `protobuf:"bytes,21,rep,name=uncles,proto3" json:"uncles,omitempty"`
|
||||
}
|
||||
|
||||
func (x *ExecutionBlock) Reset() {
|
||||
*x = ExecutionBlock{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *ExecutionBlock) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*ExecutionBlock) ProtoMessage() {}
|
||||
|
||||
func (x *ExecutionBlock) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_proto_engine_v1_execution_engine_proto_msgTypes[0]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use ExecutionBlock.ProtoReflect.Descriptor instead.
|
||||
func (*ExecutionBlock) Descriptor() ([]byte, []int) {
|
||||
return file_proto_engine_v1_execution_engine_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
func (x *ExecutionBlock) GetNumber() []byte {
|
||||
if x != nil {
|
||||
return x.Number
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *ExecutionBlock) GetHash() []byte {
|
||||
if x != nil {
|
||||
return x.Hash
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *ExecutionBlock) GetParentHash() []byte {
|
||||
if x != nil {
|
||||
return x.ParentHash
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *ExecutionBlock) GetSha3Uncles() []byte {
|
||||
if x != nil {
|
||||
return x.Sha3Uncles
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *ExecutionBlock) GetMiner() []byte {
|
||||
if x != nil {
|
||||
return x.Miner
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *ExecutionBlock) GetStateRoot() []byte {
|
||||
if x != nil {
|
||||
return x.StateRoot
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *ExecutionBlock) GetTransactionsRoot() []byte {
|
||||
if x != nil {
|
||||
return x.TransactionsRoot
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *ExecutionBlock) GetReceiptsRoot() []byte {
|
||||
if x != nil {
|
||||
return x.ReceiptsRoot
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *ExecutionBlock) GetLogsBloom() []byte {
|
||||
if x != nil {
|
||||
return x.LogsBloom
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *ExecutionBlock) GetDifficulty() []byte {
|
||||
if x != nil {
|
||||
return x.Difficulty
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *ExecutionBlock) GetTotalDifficulty() string {
|
||||
if x != nil {
|
||||
return x.TotalDifficulty
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *ExecutionBlock) GetGasLimit() uint64 {
|
||||
if x != nil {
|
||||
return x.GasLimit
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *ExecutionBlock) GetGasUsed() uint64 {
|
||||
if x != nil {
|
||||
return x.GasUsed
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *ExecutionBlock) GetBaseFeePerGas() []byte {
|
||||
if x != nil {
|
||||
return x.BaseFeePerGas
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *ExecutionBlock) GetSize() []byte {
|
||||
if x != nil {
|
||||
return x.Size
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *ExecutionBlock) GetTimestamp() uint64 {
|
||||
if x != nil {
|
||||
return x.Timestamp
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *ExecutionBlock) GetExtraData() []byte {
|
||||
if x != nil {
|
||||
return x.ExtraData
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *ExecutionBlock) GetMixHash() []byte {
|
||||
if x != nil {
|
||||
return x.MixHash
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *ExecutionBlock) GetNonce() []byte {
|
||||
if x != nil {
|
||||
return x.Nonce
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *ExecutionBlock) GetTransactions() [][]byte {
|
||||
if x != nil {
|
||||
return x.Transactions
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *ExecutionBlock) GetUncles() [][]byte {
|
||||
if x != nil {
|
||||
return x.Uncles
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type ExecutionPayload struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
@@ -1066,18 +859,6 @@ func file_proto_engine_v1_execution_engine_proto_init() {
|
||||
}
|
||||
if !protoimpl.UnsafeEnabled {
|
||||
file_proto_engine_v1_execution_engine_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*ExecutionBlock); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_proto_engine_v1_execution_engine_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*ExecutionPayload); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
@@ -1089,7 +870,7 @@ func file_proto_engine_v1_execution_engine_proto_init() {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_proto_engine_v1_execution_engine_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
|
||||
file_proto_engine_v1_execution_engine_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*ExecutionPayloadHeader); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
@@ -1101,7 +882,7 @@ func file_proto_engine_v1_execution_engine_proto_init() {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_proto_engine_v1_execution_engine_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
|
||||
file_proto_engine_v1_execution_engine_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*TransitionConfiguration); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
@@ -1113,7 +894,7 @@ func file_proto_engine_v1_execution_engine_proto_init() {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_proto_engine_v1_execution_engine_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
|
||||
file_proto_engine_v1_execution_engine_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*PayloadAttributes); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
@@ -1125,7 +906,7 @@ func file_proto_engine_v1_execution_engine_proto_init() {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_proto_engine_v1_execution_engine_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
|
||||
file_proto_engine_v1_execution_engine_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*PayloadStatus); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
@@ -1137,7 +918,7 @@ func file_proto_engine_v1_execution_engine_proto_init() {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_proto_engine_v1_execution_engine_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
|
||||
file_proto_engine_v1_execution_engine_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*ForkchoiceState); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
|
||||
@@ -24,30 +24,6 @@ option java_outer_classname = "ExecutionEngineProto";
|
||||
option java_package = "org.ethereum.engine.v1";
|
||||
option php_namespace = "Ethereum\\Engine\\v1";
|
||||
|
||||
message ExecutionBlock {
|
||||
bytes number = 1;
|
||||
bytes hash = 2;
|
||||
bytes parent_hash = 3;
|
||||
bytes sha3_uncles = 4;
|
||||
bytes miner = 5;
|
||||
bytes state_root = 6;
|
||||
bytes transactions_root = 7;
|
||||
bytes receipts_root = 8;
|
||||
bytes logs_bloom = 9;
|
||||
bytes difficulty = 10;
|
||||
string total_difficulty = 11;
|
||||
uint64 gas_limit = 12;
|
||||
uint64 gas_used = 13;
|
||||
bytes base_fee_per_gas = 14;
|
||||
bytes size = 15;
|
||||
uint64 timestamp = 16;
|
||||
bytes extra_data = 17;
|
||||
bytes mix_hash = 18;
|
||||
bytes nonce = 19;
|
||||
repeated bytes transactions = 20;
|
||||
repeated bytes uncles = 21;
|
||||
}
|
||||
|
||||
message ExecutionPayload {
|
||||
bytes parent_hash = 1 [(ethereum.eth.ext.ssz_size) = "32"];
|
||||
bytes fee_recipient = 2 [(ethereum.eth.ext.ssz_size) = "20"];
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
gethtypes "github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/pkg/errors"
|
||||
fieldparams "github.com/prysmaticlabs/prysm/config/fieldparams"
|
||||
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
||||
@@ -20,6 +21,73 @@ func (b PayloadIDBytes) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(hexutil.Bytes(b[:]))
|
||||
}
|
||||
|
||||
// ExecutionBlock is the response kind received by the eth_getBlockByHash and
|
||||
// eth_getBlockByNumber endpoints via JSON-RPC.
|
||||
type ExecutionBlock struct {
|
||||
gethtypes.Header
|
||||
Hash common.Hash `json:"hash"`
|
||||
Transactions []*gethtypes.Transaction `json:"transactions"`
|
||||
TotalDifficulty string `json:"totalDifficulty"`
|
||||
}
|
||||
|
||||
func (e *ExecutionBlock) MarshalJSON() ([]byte, error) {
|
||||
decoded := make(map[string]interface{})
|
||||
encodedHeader, err := e.Header.MarshalJSON()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := json.Unmarshal(encodedHeader, &decoded); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
encodedTxs, err := json.Marshal(e.Transactions)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
decoded["hash"] = e.Hash.String()
|
||||
decoded["transactions"] = string(encodedTxs)
|
||||
decoded["totalDifficulty"] = e.TotalDifficulty
|
||||
return json.Marshal(decoded)
|
||||
}
|
||||
|
||||
func (e *ExecutionBlock) UnmarshalJSON(enc []byte) error {
|
||||
if err := e.Header.UnmarshalJSON(enc); err != nil {
|
||||
return err
|
||||
}
|
||||
decoded := make(map[string]interface{})
|
||||
if err := json.Unmarshal(enc, &decoded); err != nil {
|
||||
return err
|
||||
}
|
||||
blockHashStr, ok := decoded["hash"].(string)
|
||||
if !ok {
|
||||
return errors.New("expected `hash` field in JSON response")
|
||||
}
|
||||
e.Hash = common.HexToHash(blockHashStr)
|
||||
e.TotalDifficulty, ok = decoded["totalDifficulty"].(string)
|
||||
if !ok {
|
||||
return errors.New("expected `totalDifficulty` field in JSON response")
|
||||
}
|
||||
txsList, ok := decoded["transactions"].([]interface{})
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
// If the block contains a list of transactions, we JSON unmarshal
|
||||
// them into a list of geth transaction objects.
|
||||
txs := make([]*gethtypes.Transaction, len(txsList))
|
||||
for i, tx := range txsList {
|
||||
t := &gethtypes.Transaction{}
|
||||
encodedTx, err := json.Marshal(tx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := json.Unmarshal(encodedTx, &t); err != nil {
|
||||
return err
|
||||
}
|
||||
txs[i] = t
|
||||
}
|
||||
e.Transactions = txs
|
||||
return nil
|
||||
}
|
||||
|
||||
// UnmarshalJSON --
|
||||
func (b *PayloadIDBytes) UnmarshalJSON(enc []byte) error {
|
||||
hexBytes := hexutil.Bytes(make([]byte, 0))
|
||||
@@ -32,133 +100,6 @@ func (b *PayloadIDBytes) UnmarshalJSON(enc []byte) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
type executionBlockJSON struct {
|
||||
Number string `json:"number"`
|
||||
Hash hexutil.Bytes `json:"hash"`
|
||||
ParentHash hexutil.Bytes `json:"parentHash"`
|
||||
Sha3Uncles hexutil.Bytes `json:"sha3Uncles"`
|
||||
Miner hexutil.Bytes `json:"miner"`
|
||||
StateRoot hexutil.Bytes `json:"stateRoot"`
|
||||
TransactionsRoot hexutil.Bytes `json:"transactionsRoot"`
|
||||
ReceiptsRoot hexutil.Bytes `json:"receiptsRoot"`
|
||||
LogsBloom hexutil.Bytes `json:"logsBloom"`
|
||||
Difficulty string `json:"difficulty"`
|
||||
TotalDifficulty string `json:"totalDifficulty"`
|
||||
GasLimit hexutil.Uint64 `json:"gasLimit"`
|
||||
GasUsed hexutil.Uint64 `json:"gasUsed"`
|
||||
Timestamp hexutil.Uint64 `json:"timestamp"`
|
||||
BaseFeePerGas string `json:"baseFeePerGas"`
|
||||
ExtraData hexutil.Bytes `json:"extraData"`
|
||||
MixHash hexutil.Bytes `json:"mixHash"`
|
||||
Nonce hexutil.Bytes `json:"nonce"`
|
||||
Size string `json:"size"`
|
||||
Transactions []hexutil.Bytes `json:"transactions"`
|
||||
Uncles []hexutil.Bytes `json:"uncles"`
|
||||
}
|
||||
|
||||
// MarshalJSON defines a custom json.Marshaler interface implementation
|
||||
// that uses custom json.Marshalers for the hexutil.Bytes and hexutil.Uint64 types.
|
||||
func (e *ExecutionBlock) MarshalJSON() ([]byte, error) {
|
||||
transactions := make([]hexutil.Bytes, len(e.Transactions))
|
||||
for i, tx := range e.Transactions {
|
||||
transactions[i] = tx
|
||||
}
|
||||
uncles := make([]hexutil.Bytes, len(e.Uncles))
|
||||
for i, ucl := range e.Uncles {
|
||||
uncles[i] = ucl
|
||||
}
|
||||
num := new(big.Int).SetBytes(e.Number)
|
||||
numHex := hexutil.EncodeBig(num)
|
||||
|
||||
diff := new(big.Int).SetBytes(e.Difficulty)
|
||||
diffHex := hexutil.EncodeBig(diff)
|
||||
|
||||
size := new(big.Int).SetBytes(e.Size)
|
||||
sizeHex := hexutil.EncodeBig(size)
|
||||
|
||||
baseFee := new(big.Int).SetBytes(bytesutil.ReverseByteOrder(e.BaseFeePerGas))
|
||||
baseFeeHex := hexutil.EncodeBig(baseFee)
|
||||
return json.Marshal(executionBlockJSON{
|
||||
Number: numHex,
|
||||
Hash: e.Hash,
|
||||
ParentHash: e.ParentHash,
|
||||
Sha3Uncles: e.Sha3Uncles,
|
||||
Miner: e.Miner,
|
||||
StateRoot: e.StateRoot,
|
||||
TransactionsRoot: e.TransactionsRoot,
|
||||
ReceiptsRoot: e.ReceiptsRoot,
|
||||
LogsBloom: e.LogsBloom,
|
||||
Difficulty: diffHex,
|
||||
TotalDifficulty: e.TotalDifficulty,
|
||||
GasLimit: hexutil.Uint64(e.GasLimit),
|
||||
GasUsed: hexutil.Uint64(e.GasUsed),
|
||||
Timestamp: hexutil.Uint64(e.Timestamp),
|
||||
ExtraData: e.ExtraData,
|
||||
MixHash: e.MixHash,
|
||||
Nonce: e.Nonce,
|
||||
Size: sizeHex,
|
||||
BaseFeePerGas: baseFeeHex,
|
||||
Transactions: transactions,
|
||||
Uncles: uncles,
|
||||
})
|
||||
}
|
||||
|
||||
// UnmarshalJSON defines a custom json.Unmarshaler interface implementation
|
||||
// that uses custom json.Unmarshalers for the hexutil.Bytes and hexutil.Uint64 types.
|
||||
func (e *ExecutionBlock) UnmarshalJSON(enc []byte) error {
|
||||
dec := executionBlockJSON{}
|
||||
if err := json.Unmarshal(enc, &dec); err != nil {
|
||||
return err
|
||||
}
|
||||
*e = ExecutionBlock{}
|
||||
num, err := hexutil.DecodeBig(dec.Number)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
e.Number = num.Bytes()
|
||||
e.Hash = dec.Hash
|
||||
e.ParentHash = dec.ParentHash
|
||||
e.Sha3Uncles = dec.Sha3Uncles
|
||||
e.Miner = dec.Miner
|
||||
e.StateRoot = dec.StateRoot
|
||||
e.TransactionsRoot = dec.TransactionsRoot
|
||||
e.ReceiptsRoot = dec.ReceiptsRoot
|
||||
e.LogsBloom = dec.LogsBloom
|
||||
diff, err := hexutil.DecodeBig(dec.Difficulty)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
e.Difficulty = diff.Bytes()
|
||||
e.TotalDifficulty = dec.TotalDifficulty
|
||||
e.GasLimit = uint64(dec.GasLimit)
|
||||
e.GasUsed = uint64(dec.GasUsed)
|
||||
e.Timestamp = uint64(dec.Timestamp)
|
||||
e.ExtraData = dec.ExtraData
|
||||
e.MixHash = dec.MixHash
|
||||
e.Nonce = dec.Nonce
|
||||
size, err := hexutil.DecodeBig(dec.Size)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
e.Size = size.Bytes()
|
||||
baseFee, err := hexutil.DecodeBig(dec.BaseFeePerGas)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
e.BaseFeePerGas = bytesutil.PadTo(bytesutil.ReverseByteOrder(baseFee.Bytes()), fieldparams.RootLength)
|
||||
transactions := make([][]byte, len(dec.Transactions))
|
||||
for i, tx := range dec.Transactions {
|
||||
transactions[i] = tx
|
||||
}
|
||||
e.Transactions = transactions
|
||||
uncles := make([][]byte, len(dec.Uncles))
|
||||
for i, ucl := range dec.Uncles {
|
||||
uncles[i] = ucl
|
||||
}
|
||||
e.Uncles = uncles
|
||||
return nil
|
||||
}
|
||||
|
||||
type executionPayloadJSON struct {
|
||||
ParentHash *common.Hash `json:"parentHash"`
|
||||
FeeRecipient *common.Address `json:"feeRecipient"`
|
||||
|
||||
@@ -5,7 +5,8 @@ import (
|
||||
"math/big"
|
||||
"testing"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
gethtypes "github.com/ethereum/go-ethereum/core/types"
|
||||
fieldparams "github.com/prysmaticlabs/prysm/config/fieldparams"
|
||||
"github.com/prysmaticlabs/prysm/config/params"
|
||||
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
||||
@@ -125,61 +126,58 @@ func TestJsonMarshalUnmarshal(t *testing.T) {
|
||||
})
|
||||
t.Run("execution block", func(t *testing.T) {
|
||||
baseFeePerGas := big.NewInt(1770307273)
|
||||
jsonPayload := &enginev1.ExecutionBlock{
|
||||
Number: []byte("100"),
|
||||
Hash: []byte("hash"),
|
||||
ParentHash: []byte("parent"),
|
||||
Sha3Uncles: []byte("sha3Uncles"),
|
||||
Miner: []byte("miner"),
|
||||
StateRoot: []byte("stateRoot"),
|
||||
TransactionsRoot: []byte("txRoot"),
|
||||
ReceiptsRoot: []byte("receiptsRoot"),
|
||||
LogsBloom: []byte("logsBloom"),
|
||||
Difficulty: []byte("1"),
|
||||
TotalDifficulty: "2",
|
||||
GasLimit: 3,
|
||||
GasUsed: 4,
|
||||
Timestamp: 5,
|
||||
BaseFeePerGas: baseFeePerGas.Bytes(),
|
||||
Size: []byte("7"),
|
||||
ExtraData: []byte("extraData"),
|
||||
MixHash: []byte("mixHash"),
|
||||
Nonce: []byte("nonce"),
|
||||
Transactions: [][]byte{[]byte("hi")},
|
||||
Uncles: [][]byte{[]byte("bye")},
|
||||
want := &gethtypes.Header{
|
||||
Number: big.NewInt(1),
|
||||
ParentHash: common.BytesToHash([]byte("parent")),
|
||||
UncleHash: common.BytesToHash([]byte("uncle")),
|
||||
Coinbase: common.BytesToAddress([]byte("coinbase")),
|
||||
Root: common.BytesToHash([]byte("uncle")),
|
||||
TxHash: common.BytesToHash([]byte("txHash")),
|
||||
ReceiptHash: common.BytesToHash([]byte("receiptHash")),
|
||||
Bloom: gethtypes.BytesToBloom([]byte("bloom")),
|
||||
Difficulty: big.NewInt(2),
|
||||
GasLimit: 3,
|
||||
GasUsed: 4,
|
||||
Time: 5,
|
||||
BaseFee: baseFeePerGas,
|
||||
Extra: []byte("extraData"),
|
||||
MixDigest: common.BytesToHash([]byte("mix")),
|
||||
Nonce: gethtypes.EncodeNonce(6),
|
||||
}
|
||||
enc, err := json.Marshal(jsonPayload)
|
||||
enc, err := json.Marshal(want)
|
||||
require.NoError(t, err)
|
||||
payloadPb := &enginev1.ExecutionBlock{}
|
||||
require.NoError(t, json.Unmarshal(enc, payloadPb))
|
||||
require.DeepEqual(t, []byte("100"), payloadPb.Number)
|
||||
require.DeepEqual(t, []byte("hash"), payloadPb.Hash)
|
||||
require.DeepEqual(t, []byte("parent"), payloadPb.ParentHash)
|
||||
require.DeepEqual(t, []byte("sha3Uncles"), payloadPb.Sha3Uncles)
|
||||
require.DeepEqual(t, []byte("miner"), payloadPb.Miner)
|
||||
require.DeepEqual(t, []byte("stateRoot"), payloadPb.StateRoot)
|
||||
require.DeepEqual(t, []byte("txRoot"), payloadPb.TransactionsRoot)
|
||||
require.DeepEqual(t, []byte("receiptsRoot"), payloadPb.ReceiptsRoot)
|
||||
require.DeepEqual(t, []byte("logsBloom"), payloadPb.LogsBloom)
|
||||
require.DeepEqual(t, []byte("1"), payloadPb.Difficulty)
|
||||
require.DeepEqual(t, "2", payloadPb.TotalDifficulty)
|
||||
require.DeepEqual(t, uint64(3), payloadPb.GasLimit)
|
||||
require.DeepEqual(t, uint64(4), payloadPb.GasUsed)
|
||||
require.DeepEqual(t, uint64(5), payloadPb.Timestamp)
|
||||
require.DeepEqual(t, bytesutil.PadTo(baseFeePerGas.Bytes(), fieldparams.RootLength), payloadPb.BaseFeePerGas)
|
||||
require.DeepEqual(t, []byte("7"), payloadPb.Size)
|
||||
require.DeepEqual(t, []byte("extraData"), payloadPb.ExtraData)
|
||||
require.DeepEqual(t, []byte("mixHash"), payloadPb.MixHash)
|
||||
require.DeepEqual(t, []byte("nonce"), payloadPb.Nonce)
|
||||
require.DeepEqual(t, [][]byte{[]byte("hi")}, payloadPb.Transactions)
|
||||
require.DeepEqual(t, [][]byte{[]byte("bye")}, payloadPb.Uncles)
|
||||
})
|
||||
t.Run("nil execution block", func(t *testing.T) {
|
||||
jsonPayload := (*enginev1.ExecutionBlock)(nil)
|
||||
enc, err := json.Marshal(jsonPayload)
|
||||
|
||||
payloadItems := make(map[string]interface{})
|
||||
require.NoError(t, json.Unmarshal(enc, &payloadItems))
|
||||
|
||||
blockHash := want.Hash()
|
||||
payloadItems["hash"] = blockHash.String()
|
||||
payloadItems["totalDifficulty"] = "0x393a2e53de197c"
|
||||
|
||||
encodedPayloadItems, err := json.Marshal(payloadItems)
|
||||
require.NoError(t, err)
|
||||
|
||||
payloadPb := &enginev1.ExecutionBlock{}
|
||||
require.ErrorIs(t, hexutil.ErrEmptyString, json.Unmarshal(enc, payloadPb))
|
||||
require.NoError(t, json.Unmarshal(encodedPayloadItems, payloadPb))
|
||||
|
||||
require.DeepEqual(t, blockHash, payloadPb.Hash)
|
||||
require.DeepEqual(t, want.Number, payloadPb.Number)
|
||||
require.DeepEqual(t, want.ParentHash, payloadPb.ParentHash)
|
||||
require.DeepEqual(t, want.UncleHash, payloadPb.UncleHash)
|
||||
require.DeepEqual(t, want.Coinbase, payloadPb.Coinbase)
|
||||
require.DeepEqual(t, want.Root, payloadPb.Root)
|
||||
require.DeepEqual(t, want.TxHash, payloadPb.TxHash)
|
||||
require.DeepEqual(t, want.ReceiptHash, payloadPb.ReceiptHash)
|
||||
require.DeepEqual(t, want.Bloom, payloadPb.Bloom)
|
||||
require.DeepEqual(t, want.Difficulty, payloadPb.Difficulty)
|
||||
require.DeepEqual(t, payloadItems["totalDifficulty"], payloadPb.TotalDifficulty)
|
||||
require.DeepEqual(t, want.GasUsed, payloadPb.GasUsed)
|
||||
require.DeepEqual(t, want.GasLimit, payloadPb.GasLimit)
|
||||
require.DeepEqual(t, want.Time, payloadPb.Time)
|
||||
require.DeepEqual(t, want.BaseFee, payloadPb.BaseFee)
|
||||
require.DeepEqual(t, want.Extra, payloadPb.Extra)
|
||||
require.DeepEqual(t, want.MixDigest, payloadPb.MixDigest)
|
||||
require.DeepEqual(t, want.Nonce, payloadPb.Nonce)
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -40,6 +40,7 @@ go_library(
|
||||
"//testing/util:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//common:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//common/hexutil:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//core/types:go_default_library",
|
||||
"@com_github_golang_snappy//:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
gethtypes "github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/blockchain"
|
||||
mock "github.com/prysmaticlabs/prysm/beacon-chain/blockchain/testing"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/cache"
|
||||
@@ -96,9 +97,11 @@ func (m *engineMock) ExecutionBlockByHash(_ context.Context, hash common.Hash) (
|
||||
td := new(big.Int).SetBytes(bytesutil.ReverseByteOrder(b.TotalDifficulty))
|
||||
tdHex := hexutil.EncodeBig(td)
|
||||
return &pb.ExecutionBlock{
|
||||
ParentHash: b.ParentHash,
|
||||
Header: gethtypes.Header{
|
||||
ParentHash: common.BytesToHash(b.ParentHash),
|
||||
},
|
||||
TotalDifficulty: tdHex,
|
||||
Hash: b.BlockHash,
|
||||
Hash: common.BytesToHash(b.BlockHash),
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user