Compare commits
3 Commits
96d5ae7897
...
57355ad8ad
Author | SHA1 | Date |
---|---|---|
|
57355ad8ad | |
|
dab746b3ef | |
|
fd550f5408 |
|
@ -33,6 +33,8 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/event"
|
"github.com/ethereum/go-ethereum/event"
|
||||||
"github.com/ethereum/go-ethereum/log"
|
"github.com/ethereum/go-ethereum/log"
|
||||||
"github.com/ethereum/go-ethereum/node"
|
"github.com/ethereum/go-ethereum/node"
|
||||||
|
"github.com/ethereum/go-ethereum/params"
|
||||||
|
"github.com/ethereum/go-ethereum/params/forks"
|
||||||
"github.com/ethereum/go-ethereum/rpc"
|
"github.com/ethereum/go-ethereum/rpc"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -95,6 +97,16 @@ type SimulatedBeacon struct {
|
||||||
lastBlockTime uint64
|
lastBlockTime uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func payloadVersion(config *params.ChainConfig, time uint64) engine.PayloadVersion {
|
||||||
|
switch config.LatestFork(time) {
|
||||||
|
case forks.Prague, forks.Cancun:
|
||||||
|
return engine.PayloadV3
|
||||||
|
case forks.Paris, forks.Shanghai:
|
||||||
|
return engine.PayloadV2
|
||||||
|
}
|
||||||
|
panic("invalid fork, simulated beacon needs to be started post-merge")
|
||||||
|
}
|
||||||
|
|
||||||
// NewSimulatedBeacon constructs a new simulated beacon chain.
|
// NewSimulatedBeacon constructs a new simulated beacon chain.
|
||||||
func NewSimulatedBeacon(period uint64, eth *eth.Ethereum) (*SimulatedBeacon, error) {
|
func NewSimulatedBeacon(period uint64, eth *eth.Ethereum) (*SimulatedBeacon, error) {
|
||||||
block := eth.BlockChain().CurrentBlock()
|
block := eth.BlockChain().CurrentBlock()
|
||||||
|
@ -107,7 +119,8 @@ func NewSimulatedBeacon(period uint64, eth *eth.Ethereum) (*SimulatedBeacon, err
|
||||||
|
|
||||||
// if genesis block, send forkchoiceUpdated to trigger transition to PoS
|
// if genesis block, send forkchoiceUpdated to trigger transition to PoS
|
||||||
if block.Number.Sign() == 0 {
|
if block.Number.Sign() == 0 {
|
||||||
if _, err := engineAPI.ForkchoiceUpdatedV3(current, nil); err != nil {
|
version := payloadVersion(eth.BlockChain().Config(), block.Time)
|
||||||
|
if _, err := engineAPI.forkchoiceUpdated(current, nil, version, false); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -171,6 +184,8 @@ func (c *SimulatedBeacon) sealBlock(withdrawals []*types.Withdrawal, timestamp u
|
||||||
return fmt.Errorf("failed to sync txpool: %w", err)
|
return fmt.Errorf("failed to sync txpool: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
version := payloadVersion(c.eth.BlockChain().Config(), timestamp)
|
||||||
|
|
||||||
var random [32]byte
|
var random [32]byte
|
||||||
rand.Read(random[:])
|
rand.Read(random[:])
|
||||||
fcResponse, err := c.engineAPI.forkchoiceUpdated(c.curForkchoiceState, &engine.PayloadAttributes{
|
fcResponse, err := c.engineAPI.forkchoiceUpdated(c.curForkchoiceState, &engine.PayloadAttributes{
|
||||||
|
@ -179,7 +194,7 @@ func (c *SimulatedBeacon) sealBlock(withdrawals []*types.Withdrawal, timestamp u
|
||||||
Withdrawals: withdrawals,
|
Withdrawals: withdrawals,
|
||||||
Random: random,
|
Random: random,
|
||||||
BeaconRoot: &common.Hash{},
|
BeaconRoot: &common.Hash{},
|
||||||
}, engine.PayloadV3, false)
|
}, version, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -204,28 +219,39 @@ func (c *SimulatedBeacon) sealBlock(withdrawals []*types.Withdrawal, timestamp u
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Independently calculate the blob hashes from sidecars.
|
var (
|
||||||
blobHashes := make([]common.Hash, 0)
|
blobHashes []common.Hash
|
||||||
if envelope.BlobsBundle != nil {
|
beaconRoot *common.Hash
|
||||||
hasher := sha256.New()
|
requests [][]byte
|
||||||
for _, commit := range envelope.BlobsBundle.Commitments {
|
)
|
||||||
var c kzg4844.Commitment
|
// Compute post-shanghai fields
|
||||||
if len(commit) != len(c) {
|
if version > engine.PayloadV2 {
|
||||||
return errors.New("invalid commitment length")
|
// Independently calculate the blob hashes from sidecars.
|
||||||
|
blobHashes = make([]common.Hash, 0)
|
||||||
|
if envelope.BlobsBundle != nil {
|
||||||
|
hasher := sha256.New()
|
||||||
|
for _, commit := range envelope.BlobsBundle.Commitments {
|
||||||
|
var c kzg4844.Commitment
|
||||||
|
if len(commit) != len(c) {
|
||||||
|
return errors.New("invalid commitment length")
|
||||||
|
}
|
||||||
|
copy(c[:], commit)
|
||||||
|
blobHashes = append(blobHashes, kzg4844.CalcBlobHashV1(hasher, &c))
|
||||||
}
|
}
|
||||||
copy(c[:], commit)
|
|
||||||
blobHashes = append(blobHashes, kzg4844.CalcBlobHashV1(hasher, &c))
|
|
||||||
}
|
}
|
||||||
|
beaconRoot = &common.Hash{}
|
||||||
|
requests = envelope.Requests
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mark the payload as canon
|
// Mark the payload as canon
|
||||||
_, err = c.engineAPI.newPayload(*payload, blobHashes, &common.Hash{}, envelope.Requests, false)
|
_, err = c.engineAPI.newPayload(*payload, blobHashes, beaconRoot, requests, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
c.setCurrentState(payload.BlockHash, finalizedHash)
|
c.setCurrentState(payload.BlockHash, finalizedHash)
|
||||||
|
|
||||||
// Mark the block containing the payload as canonical
|
// Mark the block containing the payload as canonical
|
||||||
if _, err = c.engineAPI.ForkchoiceUpdatedV3(c.curForkchoiceState, nil); err != nil {
|
if _, err = c.engineAPI.forkchoiceUpdated(c.curForkchoiceState, nil, version, false); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
c.lastBlockTime = payload.Timestamp
|
c.lastBlockTime = payload.Timestamp
|
||||||
|
|
|
@ -104,18 +104,19 @@ var DefaultProtocolID = [6]byte{'d', 'i', 's', 'c', 'v', '5'}
|
||||||
|
|
||||||
// Errors.
|
// Errors.
|
||||||
var (
|
var (
|
||||||
errTooShort = errors.New("packet too short")
|
errTooShort = errors.New("packet too short")
|
||||||
errInvalidHeader = errors.New("invalid packet header")
|
errInvalidHeader = errors.New("invalid packet header")
|
||||||
errInvalidFlag = errors.New("invalid flag value in header")
|
errInvalidFlag = errors.New("invalid flag value in header")
|
||||||
errMinVersion = errors.New("version of packet header below minimum")
|
errMinVersion = errors.New("version of packet header below minimum")
|
||||||
errMsgTooShort = errors.New("message/handshake packet below minimum size")
|
errMsgTooShort = errors.New("message/handshake packet below minimum size")
|
||||||
errAuthSize = errors.New("declared auth size is beyond packet length")
|
errAuthSize = errors.New("declared auth size is beyond packet length")
|
||||||
errUnexpectedHandshake = errors.New("unexpected auth response, not in handshake")
|
errUnexpectedHandshake = errors.New("unexpected auth response, not in handshake")
|
||||||
errInvalidAuthKey = errors.New("invalid ephemeral pubkey")
|
errInvalidAuthKey = errors.New("invalid ephemeral pubkey")
|
||||||
errNoRecord = errors.New("expected ENR in handshake but none sent")
|
errNoRecord = errors.New("expected ENR in handshake but none sent")
|
||||||
errInvalidNonceSig = errors.New("invalid ID nonce signature")
|
errInvalidNonceSig = errors.New("invalid ID nonce signature")
|
||||||
errMessageTooShort = errors.New("message contains no data")
|
errMessageTooShort = errors.New("message contains no data")
|
||||||
errMessageDecrypt = errors.New("cannot decrypt message")
|
errMessageDecrypt = errors.New("cannot decrypt message")
|
||||||
|
errChallengeAlreadySent = errors.New("challenge already sent to this node")
|
||||||
)
|
)
|
||||||
|
|
||||||
// Public errors.
|
// Public errors.
|
||||||
|
@ -217,6 +218,10 @@ func (c *Codec) Encode(id enode.ID, addr string, packet Packet, challenge *Whoar
|
||||||
|
|
||||||
// Store sent WHOAREYOU challenges.
|
// Store sent WHOAREYOU challenges.
|
||||||
if challenge, ok := packet.(*Whoareyou); ok {
|
if challenge, ok := packet.(*Whoareyou); ok {
|
||||||
|
// check if we already sent a challenge to this node
|
||||||
|
if c.sc.getHandshake(id, addr) != nil {
|
||||||
|
return nil, Nonce{}, errChallengeAlreadySent
|
||||||
|
}
|
||||||
challenge.ChallengeData = bytesCopy(&c.buf)
|
challenge.ChallengeData = bytesCopy(&c.buf)
|
||||||
c.sc.storeSentHandshake(id, addr, challenge)
|
c.sc.storeSentHandshake(id, addr, challenge)
|
||||||
} else if msgData == nil {
|
} else if msgData == nil {
|
||||||
|
|
|
@ -155,6 +155,37 @@ func TestHandshake_norecord(t *testing.T) {
|
||||||
net.nodeA.expectDecode(t, NodesMsg, nodes)
|
net.nodeA.expectDecode(t, NodesMsg, nodes)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestEncodeWhoareyouAlreadySent(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
net := newHandshakeTest()
|
||||||
|
defer net.close()
|
||||||
|
|
||||||
|
// A -> B RANDOM PACKET
|
||||||
|
packet, _ := net.nodeA.encode(t, net.nodeB, &Findnode{})
|
||||||
|
resp := net.nodeB.expectDecode(t, UnknownPacket, packet)
|
||||||
|
|
||||||
|
// A <- B First WHOAREYOU
|
||||||
|
challenge1 := &Whoareyou{
|
||||||
|
Nonce: resp.(*Unknown).Nonce,
|
||||||
|
IDNonce: testIDnonce,
|
||||||
|
RecordSeq: 0,
|
||||||
|
}
|
||||||
|
whoareyou1, _ := net.nodeB.encode(t, net.nodeA, challenge1)
|
||||||
|
net.nodeA.expectDecode(t, WhoareyouPacket, whoareyou1)
|
||||||
|
|
||||||
|
// A <- B Second WHOAREYOU (should fail)
|
||||||
|
challenge2 := &Whoareyou{
|
||||||
|
Nonce: resp.(*Unknown).Nonce,
|
||||||
|
IDNonce: testIDnonce,
|
||||||
|
RecordSeq: 0,
|
||||||
|
}
|
||||||
|
|
||||||
|
_, _, err := net.nodeB.c.Encode(net.nodeA.id(), net.nodeA.addr(), challenge2, nil)
|
||||||
|
if !errors.Is(err, errChallengeAlreadySent) {
|
||||||
|
t.Fatalf("second challenge should fail with errChallengeAlreadySent, got %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// In this test, A tries to send FINDNODE with existing secrets but B doesn't know
|
// In this test, A tries to send FINDNODE with existing secrets but B doesn't know
|
||||||
// anything about A.
|
// anything about A.
|
||||||
func TestHandshake_rekey(t *testing.T) {
|
func TestHandshake_rekey(t *testing.T) {
|
||||||
|
|
Loading…
Reference in New Issue