2022-04-01 18:04:24 +00:00
|
|
|
package testing
|
2022-03-01 21:38:51 +00:00
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
2022-04-12 10:19:07 +00:00
|
|
|
"math/big"
|
2022-03-01 21:38:51 +00:00
|
|
|
|
|
|
|
"github.com/ethereum/go-ethereum/common"
|
2022-04-12 10:19:07 +00:00
|
|
|
"github.com/ethereum/go-ethereum/common/hexutil"
|
|
|
|
"github.com/holiman/uint256"
|
2022-03-03 20:00:11 +00:00
|
|
|
"github.com/pkg/errors"
|
2022-04-12 10:19:07 +00:00
|
|
|
"github.com/prysmaticlabs/prysm/config/params"
|
|
|
|
"github.com/prysmaticlabs/prysm/encoding/bytesutil"
|
2022-03-01 21:38:51 +00:00
|
|
|
pb "github.com/prysmaticlabs/prysm/proto/engine/v1"
|
|
|
|
)
|
|
|
|
|
|
|
|
// EngineClient --
|
|
|
|
type EngineClient struct {
|
2022-04-12 10:19:07 +00:00
|
|
|
NewPayloadResp []byte
|
|
|
|
PayloadIDBytes *pb.PayloadIDBytes
|
|
|
|
ForkChoiceUpdatedResp []byte
|
|
|
|
ExecutionPayload *pb.ExecutionPayload
|
|
|
|
ExecutionBlock *pb.ExecutionBlock
|
|
|
|
Err error
|
|
|
|
ErrLatestExecBlock error
|
|
|
|
ErrExecBlockByHash error
|
|
|
|
ErrForkchoiceUpdated error
|
|
|
|
ErrNewPayload error
|
|
|
|
BlockByHashMap map[[32]byte]*pb.ExecutionBlock
|
|
|
|
TerminalBlockHash []byte
|
|
|
|
TerminalBlockHashExists bool
|
2022-05-10 20:02:00 +00:00
|
|
|
OverrideValidHash [32]byte
|
2022-03-01 21:38:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// NewPayload --
|
|
|
|
func (e *EngineClient) NewPayload(_ context.Context, _ *pb.ExecutionPayload) ([]byte, error) {
|
2022-03-31 23:14:09 +00:00
|
|
|
return e.NewPayloadResp, e.ErrNewPayload
|
2022-03-01 21:38:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// ForkchoiceUpdated --
|
|
|
|
func (e *EngineClient) ForkchoiceUpdated(
|
2022-05-10 20:02:00 +00:00
|
|
|
_ context.Context, fcs *pb.ForkchoiceState, _ *pb.PayloadAttributes,
|
2022-03-01 21:38:51 +00:00
|
|
|
) (*pb.PayloadIDBytes, []byte, error) {
|
2022-05-10 20:02:00 +00:00
|
|
|
if e.OverrideValidHash != [32]byte{} && bytesutil.ToBytes32(fcs.HeadBlockHash) == e.OverrideValidHash {
|
|
|
|
return e.PayloadIDBytes, e.ForkChoiceUpdatedResp, nil
|
|
|
|
}
|
2022-03-07 18:43:20 +00:00
|
|
|
return e.PayloadIDBytes, e.ForkChoiceUpdatedResp, e.ErrForkchoiceUpdated
|
2022-03-01 21:38:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// GetPayload --
|
|
|
|
func (e *EngineClient) GetPayload(_ context.Context, _ [8]byte) (*pb.ExecutionPayload, error) {
|
|
|
|
return e.ExecutionPayload, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// ExchangeTransitionConfiguration --
|
|
|
|
func (e *EngineClient) ExchangeTransitionConfiguration(_ context.Context, _ *pb.TransitionConfiguration) error {
|
|
|
|
return e.Err
|
|
|
|
}
|
|
|
|
|
|
|
|
// LatestExecutionBlock --
|
|
|
|
func (e *EngineClient) LatestExecutionBlock(_ context.Context) (*pb.ExecutionBlock, error) {
|
2022-03-03 20:00:11 +00:00
|
|
|
return e.ExecutionBlock, e.ErrLatestExecBlock
|
2022-03-01 21:38:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// ExecutionBlockByHash --
|
2022-03-03 20:00:11 +00:00
|
|
|
func (e *EngineClient) ExecutionBlockByHash(_ context.Context, h common.Hash) (*pb.ExecutionBlock, error) {
|
|
|
|
b, ok := e.BlockByHashMap[h]
|
|
|
|
if !ok {
|
|
|
|
return nil, errors.New("block not found")
|
|
|
|
}
|
|
|
|
return b, e.ErrExecBlockByHash
|
2022-03-01 21:38:51 +00:00
|
|
|
}
|
2022-04-12 10:19:07 +00:00
|
|
|
|
|
|
|
// GetTerminalBlockHash --
|
|
|
|
func (e *EngineClient) GetTerminalBlockHash(ctx context.Context) ([]byte, bool, error) {
|
|
|
|
ttd := new(big.Int)
|
|
|
|
ttd.SetString(params.BeaconConfig().TerminalTotalDifficulty, 10)
|
|
|
|
terminalTotalDifficulty, overflows := uint256.FromBig(ttd)
|
|
|
|
if overflows {
|
|
|
|
return nil, false, errors.New("could not convert terminal total difficulty to uint256")
|
|
|
|
}
|
|
|
|
blk, err := e.LatestExecutionBlock(ctx)
|
|
|
|
if err != nil {
|
|
|
|
return nil, false, errors.Wrap(err, "could not get latest execution block")
|
|
|
|
}
|
|
|
|
if blk == nil {
|
|
|
|
return nil, false, errors.New("latest execution block is nil")
|
|
|
|
}
|
|
|
|
|
|
|
|
for {
|
|
|
|
b, err := hexutil.DecodeBig(blk.TotalDifficulty)
|
|
|
|
if err != nil {
|
|
|
|
return nil, false, errors.Wrap(err, "could not convert total difficulty to uint256")
|
|
|
|
}
|
|
|
|
currentTotalDifficulty, _ := uint256.FromBig(b)
|
|
|
|
blockReachedTTD := currentTotalDifficulty.Cmp(terminalTotalDifficulty) >= 0
|
|
|
|
|
|
|
|
parentHash := bytesutil.ToBytes32(blk.ParentHash)
|
|
|
|
if len(blk.ParentHash) == 0 || parentHash == params.BeaconConfig().ZeroHash {
|
|
|
|
return nil, false, nil
|
|
|
|
}
|
|
|
|
parentBlk, err := e.ExecutionBlockByHash(ctx, parentHash)
|
|
|
|
if err != nil {
|
|
|
|
return nil, false, errors.Wrap(err, "could not get parent execution block")
|
|
|
|
}
|
|
|
|
if blockReachedTTD {
|
|
|
|
b, err := hexutil.DecodeBig(parentBlk.TotalDifficulty)
|
|
|
|
if err != nil {
|
|
|
|
return nil, false, errors.Wrap(err, "could not convert total difficulty to uint256")
|
|
|
|
}
|
|
|
|
parentTotalDifficulty, _ := uint256.FromBig(b)
|
|
|
|
parentReachedTTD := parentTotalDifficulty.Cmp(terminalTotalDifficulty) >= 0
|
|
|
|
if !parentReachedTTD {
|
|
|
|
return blk.Hash, true, nil
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
return nil, false, nil
|
|
|
|
}
|
|
|
|
blk = parentBlk
|
|
|
|
}
|
|
|
|
}
|