cmd/devp2p/internal/ethtest: add block hash announcement test (#22535)
This commit is contained in:
@ -633,3 +633,106 @@ func (s *Suite) maliciousStatus(conn *Conn) error {
|
||||
return fmt.Errorf("expected disconnect, got: %s", pretty.Sdump(msg))
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Suite) hashAnnounce(isEth66 bool) error {
|
||||
// create connections
|
||||
sendConn, recvConn, err := s.createSendAndRecvConns(isEth66)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create connections: %v", err)
|
||||
}
|
||||
defer sendConn.Close()
|
||||
defer recvConn.Close()
|
||||
if err := sendConn.peer(s.chain, nil); err != nil {
|
||||
return fmt.Errorf("peering failed: %v", err)
|
||||
}
|
||||
if err := recvConn.peer(s.chain, nil); err != nil {
|
||||
return fmt.Errorf("peering failed: %v", err)
|
||||
}
|
||||
// create NewBlockHashes announcement
|
||||
nextBlock := s.fullChain.blocks[s.chain.Len()]
|
||||
newBlockHash := &NewBlockHashes{
|
||||
{Hash: nextBlock.Hash(), Number: nextBlock.Number().Uint64()},
|
||||
}
|
||||
|
||||
if err := sendConn.Write(newBlockHash); err != nil {
|
||||
return fmt.Errorf("failed to write to connection: %v", err)
|
||||
}
|
||||
if isEth66 {
|
||||
// expect GetBlockHeaders request, and respond
|
||||
id, msg := sendConn.Read66()
|
||||
switch msg := msg.(type) {
|
||||
case GetBlockHeaders:
|
||||
blockHeaderReq := msg
|
||||
if blockHeaderReq.Amount != 1 {
|
||||
return fmt.Errorf("unexpected number of block headers requested: %v", blockHeaderReq.Amount)
|
||||
}
|
||||
if blockHeaderReq.Origin.Hash != nextBlock.Hash() {
|
||||
return fmt.Errorf("unexpected block header requested: %v", pretty.Sdump(blockHeaderReq))
|
||||
}
|
||||
resp := ð.BlockHeadersPacket66{
|
||||
RequestId: id,
|
||||
BlockHeadersPacket: eth.BlockHeadersPacket{
|
||||
nextBlock.Header(),
|
||||
},
|
||||
}
|
||||
if err := sendConn.Write66(resp, BlockHeaders{}.Code()); err != nil {
|
||||
return fmt.Errorf("failed to write to connection: %v", err)
|
||||
}
|
||||
default:
|
||||
return fmt.Errorf("unexpected %s", pretty.Sdump(msg))
|
||||
}
|
||||
} else {
|
||||
// expect GetBlockHeaders request, and respond
|
||||
switch msg := sendConn.Read().(type) {
|
||||
case *GetBlockHeaders:
|
||||
blockHeaderReq := *msg
|
||||
if blockHeaderReq.Amount != 1 {
|
||||
return fmt.Errorf("unexpected number of block headers requested: %v", blockHeaderReq.Amount)
|
||||
}
|
||||
if blockHeaderReq.Origin.Hash != nextBlock.Hash() {
|
||||
return fmt.Errorf("unexpected block header requested: %v", pretty.Sdump(blockHeaderReq))
|
||||
}
|
||||
if err := sendConn.Write(&BlockHeaders{nextBlock.Header()}); err != nil {
|
||||
return fmt.Errorf("failed to write to connection: %v", err)
|
||||
}
|
||||
default:
|
||||
return fmt.Errorf("unexpected %s", pretty.Sdump(msg))
|
||||
}
|
||||
}
|
||||
// wait for block announcement
|
||||
msg := recvConn.readAndServe(s.chain, timeout)
|
||||
switch msg := msg.(type) {
|
||||
case *NewBlockHashes:
|
||||
hashes := *msg
|
||||
if len(hashes) != 1 {
|
||||
return fmt.Errorf("unexpected new block hash announcement: wanted 1 announcement, got %d", len(hashes))
|
||||
}
|
||||
if nextBlock.Hash() != hashes[0].Hash {
|
||||
return fmt.Errorf("unexpected block hash announcement, wanted %v, got %v", nextBlock.Hash(),
|
||||
hashes[0].Hash)
|
||||
}
|
||||
case *NewBlock:
|
||||
// node should only propagate NewBlock without having requested the body if the body is empty
|
||||
nextBlockBody := nextBlock.Body()
|
||||
if len(nextBlockBody.Transactions) != 0 || len(nextBlockBody.Uncles) != 0 {
|
||||
return fmt.Errorf("unexpected non-empty new block propagated: %s", pretty.Sdump(msg))
|
||||
}
|
||||
if msg.Block.Hash() != nextBlock.Hash() {
|
||||
return fmt.Errorf("mismatched hash of propagated new block: wanted %v, got %v",
|
||||
nextBlock.Hash(), msg.Block.Hash())
|
||||
}
|
||||
// check to make sure header matches header that was sent to the node
|
||||
if !reflect.DeepEqual(nextBlock.Header(), msg.Block.Header()) {
|
||||
return fmt.Errorf("incorrect header received: wanted %v, got %v", nextBlock.Header(), msg.Block.Header())
|
||||
}
|
||||
default:
|
||||
return fmt.Errorf("unexpected: %s", pretty.Sdump(msg))
|
||||
}
|
||||
// confirm node imported block
|
||||
if err := s.waitForBlockImport(recvConn, nextBlock, isEth66); err != nil {
|
||||
return fmt.Errorf("error waiting for node to import new block: %v", err)
|
||||
}
|
||||
// update the chain
|
||||
s.chain.blocks = append(s.chain.blocks, nextBlock)
|
||||
return nil
|
||||
}
|
||||
|
Reference in New Issue
Block a user