diff --git a/blockdag/dag.go b/blockdag/dag.go index 963dcf2c5..4054ede9e 100644 --- a/blockdag/dag.go +++ b/blockdag/dag.go @@ -1741,7 +1741,7 @@ func (dag *BlockDAG) antiPastHeadersBetween(lowHash, highHash *daghash.Hash, max } // GetTopHeaders returns the top wire.MaxBlockHeadersPerMsg block headers ordered by blue score. -func (dag *BlockDAG) GetTopHeaders(highHash *daghash.Hash) ([]*wire.BlockHeader, error) { +func (dag *BlockDAG) GetTopHeaders(highHash *daghash.Hash, maxHeaders uint64) ([]*wire.BlockHeader, error) { highNode := &dag.virtual.blockNode if highHash != nil { highNode = dag.index.LookupNode(highHash) @@ -1754,7 +1754,7 @@ func (dag *BlockDAG) GetTopHeaders(highHash *daghash.Hash) ([]*wire.BlockHeader, queue.pushSet(highNode.parents) visited := newSet() - for i := uint32(0); queue.Len() > 0 && len(headers) < wire.MaxBlockHeadersPerMsg; i++ { + for i := uint32(0); queue.Len() > 0 && uint64(len(headers)) < maxHeaders; i++ { var current *blockNode current = queue.pop() if !visited.contains(current) { @@ -1791,9 +1791,9 @@ func (dag *BlockDAG) RUnlock() { // wire.MaxBlockHeadersPerMsg block headers. // // This function is safe for concurrent access. -func (dag *BlockDAG) AntiPastHeadersBetween(lowHash, highHash *daghash.Hash) ([]*wire.BlockHeader, error) { +func (dag *BlockDAG) AntiPastHeadersBetween(lowHash, highHash *daghash.Hash, maxHeaders uint64) ([]*wire.BlockHeader, error) { dag.dagLock.RLock() - headers, err := dag.antiPastHeadersBetween(lowHash, highHash, wire.MaxBlockHeadersPerMsg) + headers, err := dag.antiPastHeadersBetween(lowHash, highHash, maxHeaders) if err != nil { return nil, err } diff --git a/peer/log.go b/peer/log.go index 0b086dedb..9d05ad7e8 100644 --- a/peer/log.go +++ b/peer/log.go @@ -143,10 +143,6 @@ func messageSummary(msg wire.Message) string { return fmt.Sprintf("low hash %s, high hash %s", msg.LowHash, msg.HighHash) - case *wire.MsgGetHeaders: - return fmt.Sprintf("low hash %s, high hash %s", msg.LowHash, - msg.HighHash) - case *wire.MsgGetBlockLocator: return fmt.Sprintf("high hash %s, low hash %s", msg.HighHash, msg.LowHash) @@ -157,9 +153,6 @@ func messageSummary(msg wire.Message) string { } return fmt.Sprintf("no locator") - case *wire.MsgHeaders: - return fmt.Sprintf("num %d", len(msg.Headers)) - case *wire.MsgReject: // Ensure the variable length strings don't contain any // characters which are even remotely dangerous such as HTML diff --git a/peer/peer.go b/peer/peer.go index 8c76b2b32..c55d1c45a 100644 --- a/peer/peer.go +++ b/peer/peer.go @@ -164,10 +164,6 @@ type MessageListeners struct { // OnReject is invoked when a peer receives a reject kaspa message. OnReject func(p *Peer, msg *wire.MsgReject) - // OnSendHeaders is invoked when a peer receives a sendheaders kaspa - // message. - OnSendHeaders func(p *Peer, msg *wire.MsgSendHeaders) - // OnGetSelectedTip is invoked when a peer receives a getSelectedTip kaspa // message. OnGetSelectedTip func() @@ -410,16 +406,15 @@ type Peer struct { cfg Config inbound bool - flagsMtx sync.Mutex // protects the peer flags below - na *wire.NetAddress - id int32 - userAgent string - services wire.ServiceFlag - versionKnown bool - advertisedProtoVer uint32 // protocol version advertised by remote - protocolVersion uint32 // negotiated protocol version - sendHeadersPreferred bool // peer sent a sendheaders message - verAckReceived bool + flagsMtx sync.Mutex // protects the peer flags below + na *wire.NetAddress + id int32 + userAgent string + services wire.ServiceFlag + versionKnown bool + advertisedProtoVer uint32 // protocol version advertised by remote + protocolVersion uint32 // negotiated protocol version + verAckReceived bool knownInventory *mruInventoryMap prevGetBlockInvsMtx sync.Mutex @@ -717,18 +712,6 @@ func (p *Peer) TimeOffset() int64 { return timeOffset } -// WantsHeaders returns if the peer wants header messages instead of -// inventory vectors for blocks. -// -// This function is safe for concurrent access. -func (p *Peer) WantsHeaders() bool { - p.flagsMtx.Lock() - sendHeadersPreferred := p.sendHeadersPreferred - p.flagsMtx.Unlock() - - return sendHeadersPreferred -} - // localVersionMsg creates a version message that can be used to send to the // remote peer. func (p *Peer) localVersionMsg() (*wire.MsgVersion, error) { @@ -878,37 +861,6 @@ func (p *Peer) PushBlockLocatorMsg(locator blockdag.BlockLocator) error { return nil } -// PushGetHeadersMsg sends a getblockinvs message for the provided block locator -// and low hash. It will ignore back-to-back duplicate requests. -// -// This function is safe for concurrent access. -func (p *Peer) PushGetHeadersMsg(lowHash, highHash *daghash.Hash) error { - // Filter duplicate getheaders requests. - p.prevGetHdrsMtx.Lock() - isDuplicate := p.prevGetHdrsHigh != nil && p.prevGetHdrsLow != nil && - lowHash != nil && highHash.IsEqual(p.prevGetHdrsHigh) && - lowHash.IsEqual(p.prevGetHdrsLow) - p.prevGetHdrsMtx.Unlock() - - if isDuplicate { - log.Tracef("Filtering duplicate [getheaders] with low hash %s", - lowHash) - return nil - } - - // Construct the getheaders request and queue it to be sent. - msg := wire.NewMsgGetHeaders(lowHash, highHash) - p.QueueMessage(msg, nil) - - // Update the previous getheaders request information for filtering - // duplicates. - p.prevGetHdrsMtx.Lock() - p.prevGetHdrsLow = lowHash - p.prevGetHdrsHigh = highHash - p.prevGetHdrsMtx.Unlock() - return nil -} - // PushRejectMsg sends a reject message for the provided command, reject code, // reject reason, and hash. The hash will only be used when the command is a tx // or block and should be nil in other cases. The wait parameter will cause the @@ -1181,13 +1133,6 @@ func (p *Peer) maybeAddDeadline(pendingResponses map[string]time.Time, msgCmd st pendingResponses[wire.CmdTx] = deadline pendingResponses[wire.CmdNotFound] = deadline - case wire.CmdGetHeaders: - // Expects a headers message. Use a longer deadline since it - // can take a while for the remote peer to load all of the - // headers. - deadline = time.Now().Add(stallResponseTimeout * 3) - pendingResponses[wire.CmdHeaders] = deadline - case wire.CmdGetSelectedTip: // Expects a selected tip message. pendingResponses[wire.CmdSelectedTip] = deadline @@ -1510,15 +1455,6 @@ out: p.cfg.Listeners.OnReject(p, msg) } - case *wire.MsgSendHeaders: - p.flagsMtx.Lock() - p.sendHeadersPreferred = true - p.flagsMtx.Unlock() - - if p.cfg.Listeners.OnSendHeaders != nil { - p.cfg.Listeners.OnSendHeaders(p, msg) - } - case *wire.MsgGetSelectedTip: if p.cfg.Listeners.OnGetSelectedTip != nil { p.cfg.Listeners.OnGetSelectedTip() diff --git a/peer/peer_test.go b/peer/peer_test.go index fb08ea19b..29a098f11 100644 --- a/peer/peer_test.go +++ b/peer/peer_test.go @@ -394,9 +394,6 @@ func TestPeerListeners(t *testing.T) { OnReject: func(p *peer.Peer, msg *wire.MsgReject) { ok <- msg }, - OnSendHeaders: func(p *peer.Peer, msg *wire.MsgSendHeaders) { - ok <- msg - }, }, UserAgentName: "peer", UserAgentVersion: "1.0", @@ -505,10 +502,6 @@ func TestPeerListeners(t *testing.T) { "OnReject", wire.NewMsgReject("block", wire.RejectDuplicate, "dupe block"), }, - { - "OnSendHeaders", - wire.NewMsgSendHeaders(), - }, } t.Logf("Running %d tests", len(tests)) for _, test := range tests { @@ -618,10 +611,6 @@ func TestOutboundPeer(t *testing.T) { t.Errorf("PushGetBlockInvsMsg: unexpected err %v\n", err) return } - if err := p2.PushGetHeadersMsg(nil, &daghash.Hash{}); err != nil { - t.Errorf("PushGetHeadersMsg: unexpected err %v\n", err) - return - } p2.PushRejectMsg("block", wire.RejectMalformed, "malformed", nil, false) p2.PushRejectMsg("block", wire.RejectInvalid, "invalid", nil, false) @@ -630,7 +619,6 @@ func TestOutboundPeer(t *testing.T) { p2.QueueMessage(wire.NewMsgGetAddr(false, nil), nil) p2.QueueMessage(wire.NewMsgPing(1), nil) p2.QueueMessage(wire.NewMsgGetData(), nil) - p2.QueueMessage(wire.NewMsgGetHeaders(&daghash.ZeroHash, &daghash.ZeroHash), nil) p2.QueueMessage(wire.NewMsgFeeFilter(20000), nil) p2.Disconnect() diff --git a/server/p2p/p2p.go b/server/p2p/p2p.go index 8aa539fd6..fc50a500b 100644 --- a/server/p2p/p2p.go +++ b/server/p2p/p2p.go @@ -750,26 +750,6 @@ func (s *Server) handleRelayInvMsg(state *peerState, msg relayMsg) { return true } - // If the inventory is a block and the peer prefers headers, - // generate and send a headers message instead of an inventory - // message. - if msg.invVect.Type == wire.InvTypeBlock && sp.WantsHeaders() { - blockHeader, ok := msg.data.(wire.BlockHeader) - if !ok { - peerLog.Warnf("Underlying data for headers" + - " is not a block header") - return true - } - msgHeaders := wire.NewMsgHeaders() - if err := msgHeaders.AddBlockHeader(&blockHeader); err != nil { - peerLog.Errorf("Failed to add block"+ - " header: %s", err) - return true - } - sp.QueueMessage(msgHeaders, nil) - return true - } - if msg.invVect.Type == wire.InvTypeTx { // Don't relay the transaction to the peer when it has // transaction relaying disabled. diff --git a/server/rpc/handle_get_headers.go b/server/rpc/handle_get_headers.go index 7065ecc2d..3bca75a9c 100644 --- a/server/rpc/handle_get_headers.go +++ b/server/rpc/handle_get_headers.go @@ -7,6 +7,8 @@ import ( "github.com/kaspanet/kaspad/util/daghash" ) +const getHeadersMaxHeaders = 2000 + // handleGetHeaders implements the getHeaders command. func handleGetHeaders(s *Server, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { c := cmd.(*rpcmodel.GetHeadersCmd) @@ -25,7 +27,7 @@ func handleGetHeaders(s *Server, cmd interface{}, closeChan <-chan struct{}) (in return nil, rpcDecodeHexError(c.HighHash) } } - headers, err := s.cfg.SyncMgr.AntiPastHeadersBetween(lowHash, highHash) + headers, err := s.cfg.SyncMgr.AntiPastHeadersBetween(lowHash, highHash, getHeadersMaxHeaders) if err != nil { return nil, &rpcmodel.RPCError{ Code: rpcmodel.ErrRPCMisc, diff --git a/server/rpc/handle_get_top_headers.go b/server/rpc/handle_get_top_headers.go index d34b99e29..119de437f 100644 --- a/server/rpc/handle_get_top_headers.go +++ b/server/rpc/handle_get_top_headers.go @@ -7,6 +7,8 @@ import ( "github.com/kaspanet/kaspad/util/daghash" ) +const getTopHeadersMaxHeaders = getHeadersMaxHeaders + // handleGetTopHeaders implements the getTopHeaders command. func handleGetTopHeaders(s *Server, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { c := cmd.(*rpcmodel.GetTopHeadersCmd) @@ -19,7 +21,7 @@ func handleGetTopHeaders(s *Server, cmd interface{}, closeChan <-chan struct{}) return nil, rpcDecodeHexError(*c.HighHash) } } - headers, err := s.cfg.DAG.GetTopHeaders(highHash) + headers, err := s.cfg.DAG.GetTopHeaders(highHash, getTopHeadersMaxHeaders) if err != nil { return nil, internalRPCError(err.Error(), "Failed to get top headers") diff --git a/server/rpc/rpcadapters.go b/server/rpc/rpcadapters.go index 3bee00618..506ccf82b 100644 --- a/server/rpc/rpcadapters.go +++ b/server/rpc/rpcadapters.go @@ -275,6 +275,6 @@ func (b *rpcSyncMgr) SyncPeerID() int32 { // // This function is safe for concurrent access and is part of the // rpcserverSyncManager interface implementation. -func (b *rpcSyncMgr) AntiPastHeadersBetween(lowHash, highHash *daghash.Hash) ([]*wire.BlockHeader, error) { - return b.server.DAG.AntiPastHeadersBetween(lowHash, highHash) +func (b *rpcSyncMgr) AntiPastHeadersBetween(lowHash, highHash *daghash.Hash, maxHeaders uint64) ([]*wire.BlockHeader, error) { + return b.server.DAG.AntiPastHeadersBetween(lowHash, highHash, maxHeaders) } diff --git a/server/rpc/rpcserver.go b/server/rpc/rpcserver.go index 6ae7ef830..b61f97c4f 100644 --- a/server/rpc/rpcserver.go +++ b/server/rpc/rpcserver.go @@ -739,7 +739,7 @@ type rpcserverSyncManager interface { // AntiPastHeadersBetween returns the headers of the blocks between the // lowHash's antiPast and highHash's antiPast, or up to // wire.MaxBlockHeadersPerMsg block headers. - AntiPastHeadersBetween(lowHash, highHash *daghash.Hash) ([]*wire.BlockHeader, error) + AntiPastHeadersBetween(lowHash, highHash *daghash.Hash, maxHeaders uint64) ([]*wire.BlockHeader, error) } // rpcserverConfig is a descriptor containing the RPC server configuration. diff --git a/wire/bench_test.go b/wire/bench_test.go index ae3039070..aa94bffc1 100644 --- a/wire/bench_test.go +++ b/wire/bench_test.go @@ -374,69 +374,6 @@ func BenchmarkWriteBlockHeader(b *testing.B) { } } -// BenchmarkDecodeGetHeaders performs a benchmark on how long it takes to -// decode a getheaders message. -func BenchmarkDecodeGetHeaders(b *testing.B) { - pver := ProtocolVersion - var m MsgGetHeaders - m.LowHash = &daghash.Hash{1} - m.HighHash = &daghash.Hash{1} - - // Serialize it so the bytes are available to test the decode below. - var bb bytes.Buffer - if err := m.KaspaEncode(&bb, pver); err != nil { - b.Fatalf("MsgGetHeaders.KaspaEncode: unexpected error: %v", err) - } - buf := bb.Bytes() - - r := bytes.NewReader(buf) - var msg MsgGetHeaders - b.ResetTimer() - for i := 0; i < b.N; i++ { - r.Seek(0, 0) - msg.KaspaDecode(r, pver) - } -} - -// BenchmarkDecodeHeaders performs a benchmark on how long it takes to -// decode a headers message with the maximum number of headers and maximum number of -// parent hashes per header. -func BenchmarkDecodeHeaders(b *testing.B) { - // Create a message with the maximum number of headers. - pver := ProtocolVersion - var m MsgHeaders - for i := 0; i < MaxBlockHeadersPerMsg; i++ { - hash, err := daghash.NewHashFromStr(fmt.Sprintf("%x", i)) - if err != nil { - b.Fatalf("NewHashFromStr: unexpected error: %v", err) - } - parentHashes := make([]*daghash.Hash, MaxNumParentBlocks) - for j := byte(0); j < MaxNumParentBlocks; j++ { - hash, err := daghash.NewHashFromStr(fmt.Sprintf("%x%x", i, j)) - if err != nil { - b.Fatalf("NewHashFromStr: unexpected error: %v", err) - } - parentHashes[i] = hash - } - m.AddBlockHeader(NewBlockHeader(1, parentHashes, hash, hash, hash, 0, uint64(i))) - } - - // Serialize it so the bytes are available to test the decode below. - var bb bytes.Buffer - if err := m.KaspaEncode(&bb, pver); err != nil { - b.Fatalf("MsgHeaders.KaspaEncode: unexpected error: %v", err) - } - buf := bb.Bytes() - - r := bytes.NewReader(buf) - var msg MsgHeaders - b.ResetTimer() - for i := 0; i < b.N; i++ { - r.Seek(0, 0) - msg.KaspaDecode(r, pver) - } -} - // BenchmarkDecodeGetBlockInvs performs a benchmark on how long it takes to // decode a getblockinvs message. func BenchmarkDecodeGetBlockInvs(b *testing.B) { diff --git a/wire/message.go b/wire/message.go index bc3c88c08..e2a65f5cf 100644 --- a/wire/message.go +++ b/wire/message.go @@ -39,8 +39,6 @@ const ( CmdNotFound = "notfound" CmdBlock = "block" CmdTx = "tx" - CmdGetHeaders = "getheaders" - CmdHeaders = "headers" CmdPing = "ping" CmdPong = "pong" CmdFilterAdd = "filteradd" @@ -48,7 +46,6 @@ const ( CmdFilterLoad = "filterload" CmdMerkleBlock = "merkleblock" CmdReject = "reject" - CmdSendHeaders = "sendheaders" CmdFeeFilter = "feefilter" CmdGetBlockLocator = "getlocator" CmdBlockLocator = "locator" @@ -114,12 +111,6 @@ func makeEmptyMessage(command string) (Message, error) { case CmdPong: msg = &MsgPong{} - case CmdGetHeaders: - msg = &MsgGetHeaders{} - - case CmdHeaders: - msg = &MsgHeaders{} - case CmdFilterAdd: msg = &MsgFilterAdd{} @@ -135,9 +126,6 @@ func makeEmptyMessage(command string) (Message, error) { case CmdReject: msg = &MsgReject{} - case CmdSendHeaders: - msg = &MsgSendHeaders{} - case CmdFeeFilter: msg = &MsgFeeFilter{} diff --git a/wire/message_test.go b/wire/message_test.go index aa25209cb..9e042c763 100644 --- a/wire/message_test.go +++ b/wire/message_test.go @@ -60,12 +60,9 @@ func TestMessage(t *testing.T) { msgTx := NewNativeMsgTx(1, nil, nil) msgPing := NewMsgPing(123123) msgPong := NewMsgPong(123123) - msgGetHeaders := NewMsgGetHeaders(&daghash.Hash{}, &daghash.Hash{}) msgGetBlockLocator := NewMsgGetBlockLocator(&daghash.ZeroHash, &daghash.ZeroHash) msgBlockLocator := NewMsgBlockLocator() - msgSendHeaders := NewMsgSendHeaders() msgFeeFilter := NewMsgFeeFilter(123456) - msgHeaders := NewMsgHeaders() msgFilterAdd := NewMsgFilterAdd([]byte{0x01}) msgFilterClear := NewMsgFilterClear() msgFilterLoad := NewMsgFilterLoad([]byte{0x01}, 10, 0, BloomUpdateNone) @@ -92,12 +89,9 @@ func TestMessage(t *testing.T) { {msgTx, msgTx, pver, Mainnet, 58}, {msgPing, msgPing, pver, Mainnet, 32}, {msgPong, msgPong, pver, Mainnet, 32}, - {msgGetHeaders, msgGetHeaders, pver, Mainnet, 88}, {msgGetBlockLocator, msgGetBlockLocator, pver, Mainnet, 88}, {msgBlockLocator, msgBlockLocator, pver, Mainnet, 25}, - {msgSendHeaders, msgSendHeaders, pver, Mainnet, 24}, {msgFeeFilter, msgFeeFilter, pver, Mainnet, 32}, - {msgHeaders, msgHeaders, pver, Mainnet, 25}, {msgFilterAdd, msgFilterAdd, pver, Mainnet, 26}, {msgFilterClear, msgFilterClear, pver, Mainnet, 24}, {msgFilterLoad, msgFilterLoad, pver, Mainnet, 35}, diff --git a/wire/msggetheaders.go b/wire/msggetheaders.go deleted file mode 100644 index 933501d1c..000000000 --- a/wire/msggetheaders.go +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright (c) 2013-2016 The btcsuite developers -// Use of this source code is governed by an ISC -// license that can be found in the LICENSE file. - -package wire - -import ( - "io" - - "github.com/kaspanet/kaspad/util/daghash" -) - -// MsgGetHeaders implements the Message interface and represents a kaspa -// getheaders message. It is used to request a list of block headers for -// blocks starting after the last known hash in the slice of block locator -// hashes. The list is returned via a headers message (MsgHeaders) and is -// limited by a specific hash to stop at or the maximum number of block headers -// per message, which is currently 2000. -// -// Set the HighHash field to the hash at which to stop and use -// AddBlockLocatorHash to build up the list of block locator hashes. -// -// The algorithm for building the block locator hashes should be to add the -// hashes in reverse order until you reach the genesis block. In order to keep -// the list of locator hashes to a resonable number of entries, first add the -// most recent 10 block hashes, then double the step each loop iteration to -// exponentially decrease the number of hashes the further away from head and -// closer to the genesis block you get. -type MsgGetHeaders struct { - LowHash *daghash.Hash - HighHash *daghash.Hash -} - -// KaspaDecode decodes r using the kaspa protocol encoding into the receiver. -// This is part of the Message interface implementation. -func (msg *MsgGetHeaders) KaspaDecode(r io.Reader, pver uint32) error { - msg.LowHash = &daghash.Hash{} - err := ReadElement(r, msg.LowHash) - if err != nil { - return err - } - - msg.HighHash = &daghash.Hash{} - return ReadElement(r, msg.HighHash) -} - -// KaspaEncode encodes the receiver to w using the kaspa protocol encoding. -// This is part of the Message interface implementation. -func (msg *MsgGetHeaders) KaspaEncode(w io.Writer, pver uint32) error { - err := WriteElement(w, msg.LowHash) - if err != nil { - return err - } - - return WriteElement(w, msg.HighHash) -} - -// Command returns the protocol command string for the message. This is part -// of the Message interface implementation. -func (msg *MsgGetHeaders) Command() string { - return CmdGetHeaders -} - -// MaxPayloadLength returns the maximum length the payload can be for the -// receiver. This is part of the Message interface implementation. -func (msg *MsgGetHeaders) MaxPayloadLength(pver uint32) uint32 { - // low hash + high hash. - return 2 * daghash.HashSize -} - -// NewMsgGetHeaders returns a new kaspa getheaders message that conforms to -// the Message interface. See MsgGetHeaders for details. -func NewMsgGetHeaders(lowHash, highHash *daghash.Hash) *MsgGetHeaders { - return &MsgGetHeaders{ - LowHash: lowHash, - HighHash: highHash, - } -} diff --git a/wire/msggetheaders_test.go b/wire/msggetheaders_test.go deleted file mode 100644 index 305f918a1..000000000 --- a/wire/msggetheaders_test.go +++ /dev/null @@ -1,227 +0,0 @@ -// Copyright (c) 2013-2016 The btcsuite developers -// Use of this source code is governed by an ISC -// license that can be found in the LICENSE file. - -package wire - -import ( - "bytes" - "github.com/pkg/errors" - "io" - "reflect" - "testing" - - "github.com/davecgh/go-spew/spew" - "github.com/kaspanet/kaspad/util/daghash" -) - -// TestGetHeaders tests the MsgGetHeader API. -func TestGetHeaders(t *testing.T) { - pver := ProtocolVersion - - // Block 99500 hash. - hashStr := "000000000002e7ad7b9eef9479e4aabc65cb831269cc20d2632c13684406dee0" - lowHash, err := daghash.NewHashFromStr(hashStr) - if err != nil { - t.Errorf("NewHashFromStr: %v", err) - } - - // Ensure the command is expected value. - wantCmd := "getheaders" - msg := NewMsgGetHeaders(lowHash, &daghash.ZeroHash) - if cmd := msg.Command(); cmd != wantCmd { - t.Errorf("NewMsgGetHeaders: wrong command - got %v want %v", - cmd, wantCmd) - } - - // Ensure max payload is low hash (32 bytes) + high hash (32 bytes).. - wantPayload := uint32(64) - maxPayload := msg.MaxPayloadLength(pver) - if maxPayload != wantPayload { - t.Errorf("MaxPayloadLength: wrong max payload length for "+ - "protocol version %d - got %v, want %v", pver, - maxPayload, wantPayload) - } -} - -// TestGetHeadersWire tests the MsgGetHeaders wire encode and decode. -func TestGetHeadersWire(t *testing.T) { - hashStr := "2710f40c87ec93d010a6fd95f42c59a2cbacc60b18cf6b7957535" - lowHash, err := daghash.NewHashFromStr(hashStr) - if err != nil { - t.Errorf("NewHashFromStr: %v", err) - } - - hashStr = "3ba27aa200b1cecaad478d2b00432346c3f1f3986da1afd33e506" - highHash, err := daghash.NewHashFromStr(hashStr) - if err != nil { - t.Errorf("NewHashFromStr: %v", err) - } - - // MsgGetHeaders message with no block locators or high hash. - noLowAndHighHash := NewMsgGetHeaders(&daghash.ZeroHash, &daghash.ZeroHash) - noLowAndHighHashEncoded := []byte{ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Low hash - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // High hash - } - - // MsgGetHeaders message with multiple block locators and a high hash. - withLowAndHighHash := NewMsgGetHeaders(lowHash, highHash) - withLowAndHighHashEncoded := []byte{ - 0x35, 0x75, 0x95, 0xb7, 0xf6, 0x8c, 0xb1, 0x60, - 0xcc, 0xba, 0x2c, 0x9a, 0xc5, 0x42, 0x5f, 0xd9, - 0x6f, 0x0a, 0x01, 0x3d, 0xc9, 0x7e, 0xc8, 0x40, - 0x0f, 0x71, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, // Low hash - 0x06, 0xe5, 0x33, 0xfd, 0x1a, 0xda, 0x86, 0x39, - 0x1f, 0x3f, 0x6c, 0x34, 0x32, 0x04, 0xb0, 0xd2, - 0x78, 0xd4, 0xaa, 0xec, 0x1c, 0x0b, 0x20, 0xaa, - 0x27, 0xba, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, // High hash - } - - tests := []struct { - in *MsgGetHeaders // Message to encode - out *MsgGetHeaders // Expected decoded message - buf []byte // Wire encoding - pver uint32 // Protocol version for wire encoding - }{ - // Message with no low hash and high hash. - { - noLowAndHighHash, - noLowAndHighHash, - noLowAndHighHashEncoded, - ProtocolVersion, - }, - - // Message with low hash and high hash. - { - withLowAndHighHash, - withLowAndHighHash, - withLowAndHighHashEncoded, - ProtocolVersion, - }, - } - - t.Logf("Running %d tests", len(tests)) - for i, test := range tests { - // Encode the message to wire format. - var buf bytes.Buffer - err := test.in.KaspaEncode(&buf, test.pver) - if err != nil { - t.Errorf("KaspaEncode #%d error %v", i, err) - continue - } - if !bytes.Equal(buf.Bytes(), test.buf) { - t.Errorf("KaspaEncode #%d\n got: %s want: %s", i, - spew.Sdump(buf.Bytes()), spew.Sdump(test.buf)) - continue - } - - // Decode the message from wire format. - var msg MsgGetHeaders - rbuf := bytes.NewReader(test.buf) - err = msg.KaspaDecode(rbuf, test.pver) - if err != nil { - t.Errorf("KaspaDecode #%d error %v", i, err) - continue - } - if !reflect.DeepEqual(&msg, test.out) { - t.Errorf("KaspaDecode #%d\n got: %s want: %s", i, - spew.Sdump(&msg), spew.Sdump(test.out)) - continue - } - } -} - -// TestGetHeadersWireErrors performs negative tests against wire encode and -// decode of MsgGetHeaders to confirm error paths work correctly. -func TestGetHeadersWireErrors(t *testing.T) { - // Set protocol inside getheaders message. - pver := ProtocolVersion - - hashStr := "2710f40c87ec93d010a6fd95f42c59a2cbacc60b18cf6b7957535" - lowHash, err := daghash.NewHashFromStr(hashStr) - if err != nil { - t.Errorf("NewHashFromStr: %v", err) - } - - hashStr = "3ba27aa200b1cecaad478d2b00432346c3f1f3986da1afd33e506" - highHash, err := daghash.NewHashFromStr(hashStr) - if err != nil { - t.Errorf("NewHashFromStr: %v", err) - } - - // MsgGetHeaders message with multiple block locators and a high hash. - baseGetHeaders := NewMsgGetHeaders(lowHash, highHash) - baseGetHeadersEncoded := []byte{ - 0x35, 0x75, 0x95, 0xb7, 0xf6, 0x8c, 0xb1, 0x60, - 0xcc, 0xba, 0x2c, 0x9a, 0xc5, 0x42, 0x5f, 0xd9, - 0x6f, 0x0a, 0x01, 0x3d, 0xc9, 0x7e, 0xc8, 0x40, - 0x0f, 0x71, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, // Low hash - 0x06, 0xe5, 0x33, 0xfd, 0x1a, 0xda, 0x86, 0x39, - 0x1f, 0x3f, 0x6c, 0x34, 0x32, 0x04, 0xb0, 0xd2, - 0x78, 0xd4, 0xaa, 0xec, 0x1c, 0x0b, 0x20, 0xaa, - 0x27, 0xba, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, // High hash - } - - tests := []struct { - in *MsgGetHeaders // Value to encode - buf []byte // Wire encoding - pver uint32 // Protocol version for wire encoding - max int // Max size of fixed buffer to induce errors - writeErr error // Expected write error - readErr error // Expected read error - }{ - // Force error in low hash. - {baseGetHeaders, baseGetHeadersEncoded, pver, 0, io.ErrShortWrite, io.EOF}, - // Force error in high hash. - {baseGetHeaders, baseGetHeadersEncoded, pver, 32, io.ErrShortWrite, io.EOF}, - } - - t.Logf("Running %d tests", len(tests)) - for i, test := range tests { - // Encode to wire format. - w := newFixedWriter(test.max) - err := test.in.KaspaEncode(w, test.pver) - if reflect.TypeOf(err) != reflect.TypeOf(test.writeErr) { - t.Errorf("KaspaEncode #%d wrong error got: %v, want: %v", - i, err, test.writeErr) - continue - } - - // For errors which are not of type MessageError, check them for - // equality. - if msgErr := &(MessageError{}); !errors.As(err, &msgErr) { - if err != test.writeErr { - t.Errorf("KaspaEncode #%d wrong error got: %v, "+ - "want: %v", i, err, test.writeErr) - continue - } - } - - // Decode from wire format. - var msg MsgGetHeaders - r := newFixedReader(test.max, test.buf) - err = msg.KaspaDecode(r, test.pver) - if reflect.TypeOf(err) != reflect.TypeOf(test.readErr) { - t.Errorf("KaspaDecode #%d wrong error got: %v, want: %v", - i, err, test.readErr) - continue - } - - // For errors which are not of type MessageError, check them for - // equality. - if msgErr := &(MessageError{}); !errors.As(err, &msgErr) { - if err != test.readErr { - t.Errorf("KaspaDecode #%d wrong error got: %v, "+ - "want: %v", i, err, test.readErr) - continue - } - } - } -} diff --git a/wire/msgheaders.go b/wire/msgheaders.go deleted file mode 100644 index c459479c2..000000000 --- a/wire/msgheaders.go +++ /dev/null @@ -1,136 +0,0 @@ -// Copyright (c) 2013-2016 The btcsuite developers -// Use of this source code is governed by an ISC -// license that can be found in the LICENSE file. - -package wire - -import ( - "fmt" - "io" -) - -// MaxBlockHeadersPerMsg is the maximum number of block headers that can be in -// a single kaspa headers message. -const MaxBlockHeadersPerMsg = 2000 - -// MsgHeaders implements the Message interface and represents a kaspa headers -// message. It is used to deliver block header information in response -// to a getheaders message (MsgGetHeaders). The maximum number of block headers -// per message is currently 2000. See MsgGetHeaders for details on requesting -// the headers. -type MsgHeaders struct { - Headers []*BlockHeader -} - -// AddBlockHeader adds a new block header to the message. -func (msg *MsgHeaders) AddBlockHeader(bh *BlockHeader) error { - if len(msg.Headers)+1 > MaxBlockHeadersPerMsg { - str := fmt.Sprintf("too many block headers in message [max %d]", - MaxBlockHeadersPerMsg) - return messageError("MsgHeaders.AddBlockHeader", str) - } - - msg.Headers = append(msg.Headers, bh) - return nil -} - -// KaspaDecode decodes r using the kaspa protocol encoding into the receiver. -// This is part of the Message interface implementation. -func (msg *MsgHeaders) KaspaDecode(r io.Reader, pver uint32) error { - count, err := ReadVarInt(r) - if err != nil { - return err - } - - // Limit to max block headers per message. - if count > MaxBlockHeadersPerMsg { - str := fmt.Sprintf("too many block headers for message "+ - "[count %d, max %d]", count, MaxBlockHeadersPerMsg) - return messageError("MsgHeaders.KaspaDecode", str) - } - - // Create a contiguous slice of headers to deserialize into in order to - // reduce the number of allocations. - headers := make([]BlockHeader, count) - msg.Headers = make([]*BlockHeader, 0, count) - for i := uint64(0); i < count; i++ { - bh := &headers[i] - err := readBlockHeader(r, pver, bh) - if err != nil { - return err - } - - txCount, err := ReadVarInt(r) - if err != nil { - return err - } - - // Ensure the transaction count is zero for headers. - if txCount > 0 { - str := fmt.Sprintf("block headers may not contain "+ - "transactions [count %d]", txCount) - return messageError("MsgHeaders.KaspaDecode", str) - } - msg.AddBlockHeader(bh) - } - - return nil -} - -// KaspaEncode encodes the receiver to w using the kaspa protocol encoding. -// This is part of the Message interface implementation. -func (msg *MsgHeaders) KaspaEncode(w io.Writer, pver uint32) error { - // Limit to max block headers per message. - count := len(msg.Headers) - if count > MaxBlockHeadersPerMsg { - str := fmt.Sprintf("too many block headers for message "+ - "[count %d, max %d]", count, MaxBlockHeadersPerMsg) - return messageError("MsgHeaders.KaspaEncode", str) - } - - err := WriteVarInt(w, uint64(count)) - if err != nil { - return err - } - - for _, bh := range msg.Headers { - err := writeBlockHeader(w, pver, bh) - if err != nil { - return err - } - - // The wire protocol encoding always includes a 0 for the number - // of transactions on header messages. This is really just an - // artifact of the way the original implementation serializes - // block headers, but it is required. - err = WriteVarInt(w, 0) - if err != nil { - return err - } - } - - return nil -} - -// Command returns the protocol command string for the message. This is part -// of the Message interface implementation. -func (msg *MsgHeaders) Command() string { - return CmdHeaders -} - -// MaxPayloadLength returns the maximum length the payload can be for the -// receiver. This is part of the Message interface implementation. -func (msg *MsgHeaders) MaxPayloadLength(pver uint32) uint32 { - // Num headers (varInt) + max allowed headers (header length + 1 byte - // for the number of transactions which is always 0). - return MaxVarIntPayload + ((MaxBlockHeaderPayload + 1) * - MaxBlockHeadersPerMsg) -} - -// NewMsgHeaders returns a new kaspa headers message that conforms to the -// Message interface. See MsgHeaders for details. -func NewMsgHeaders() *MsgHeaders { - return &MsgHeaders{ - Headers: make([]*BlockHeader, 0, MaxBlockHeadersPerMsg), - } -} diff --git a/wire/msgheaders_test.go b/wire/msgheaders_test.go deleted file mode 100644 index 86b3d5c05..000000000 --- a/wire/msgheaders_test.go +++ /dev/null @@ -1,329 +0,0 @@ -// Copyright (c) 2013-2016 The btcsuite developers -// Use of this source code is governed by an ISC -// license that can be found in the LICENSE file. - -package wire - -import ( - "bytes" - "github.com/pkg/errors" - "io" - "reflect" - "testing" - - "github.com/davecgh/go-spew/spew" - "github.com/kaspanet/kaspad/util/daghash" -) - -// TestHeaders tests the MsgHeaders API. -func TestHeaders(t *testing.T) { - pver := ProtocolVersion - - // Ensure the command is expected value. - wantCmd := "headers" - msg := NewMsgHeaders() - if cmd := msg.Command(); cmd != wantCmd { - t.Errorf("NewMsgHeaders: wrong command - got %v want %v", - cmd, wantCmd) - } - - // Ensure max payload is expected value for latest protocol version. - // Num headers (varInt) + max allowed headers (header length + 1 byte - // for the number of transactions which is always 0). - wantPayload := uint32(16564009) - maxPayload := msg.MaxPayloadLength(pver) - if maxPayload != wantPayload { - t.Errorf("MaxPayloadLength: wrong max payload length for "+ - "protocol version %d - got %v, want %v", pver, - maxPayload, wantPayload) - } - - // Ensure headers are added properly. - bh := &blockOne.Header - msg.AddBlockHeader(bh) - if !reflect.DeepEqual(msg.Headers[0], bh) { - t.Errorf("AddHeader: wrong header - got %v, want %v", - spew.Sdump(msg.Headers), - spew.Sdump(bh)) - } - - // Ensure adding more than the max allowed headers per message returns - // error. - var err error - for i := 0; i < MaxBlockHeadersPerMsg+1; i++ { - err = msg.AddBlockHeader(bh) - } - if reflect.TypeOf(err) != reflect.TypeOf(&MessageError{}) { - t.Errorf("AddBlockHeader: expected error on too many headers " + - "not received") - } -} - -// TestHeadersWire tests the MsgHeaders wire encode and decode for various -// numbers of headers and protocol versions. -func TestHeadersWire(t *testing.T) { - hashes := []*daghash.Hash{mainnetGenesisHash, simnetGenesisHash} - hashMerkleRoot := blockOne.Header.HashMerkleRoot - acceptedIDMerkleRoot := blockOne.Header.AcceptedIDMerkleRoot - utxoCommitment := blockOne.Header.UTXOCommitment - bits := uint32(0x1d00ffff) - nonce := uint64(0x9962e301) - bh := NewBlockHeader(1, hashes, hashMerkleRoot, acceptedIDMerkleRoot, utxoCommitment, bits, nonce) - bh.Version = blockOne.Header.Version - bh.Timestamp = blockOne.Header.Timestamp - - // Empty headers message. - noHeaders := NewMsgHeaders() - noHeadersEncoded := []byte{ - 0x00, // Varint for number of headers - } - - // Headers message with one header. - oneHeader := NewMsgHeaders() - oneHeader.AddBlockHeader(bh) - oneHeaderEncoded := []byte{ - 0x01, // VarInt for number of headers. - 0x01, 0x00, 0x00, 0x00, // Version 1 - 0x02, // NumParentBlocks - 0xdc, 0x5f, 0x5b, 0x5b, 0x1d, 0xc2, 0xa7, 0x25, // mainnetGenesisHash - 0x49, 0xd5, 0x1d, 0x4d, 0xee, 0xd7, 0xa4, 0x8b, - 0xaf, 0xd3, 0x14, 0x4b, 0x56, 0x78, 0x98, 0xb1, - 0x8c, 0xfd, 0x9f, 0x69, 0xdd, 0xcf, 0xbb, 0x63, - 0xf6, 0x7a, 0xd7, 0x69, 0x5d, 0x9b, 0x66, 0x2a, // simnetGenesisHash - 0x72, 0xff, 0x3d, 0x8e, 0xdb, 0xbb, 0x2d, 0xe0, - 0xbf, 0xa6, 0x7b, 0x13, 0x97, 0x4b, 0xb9, 0x91, - 0x0d, 0x11, 0x6d, 0x5c, 0xbd, 0x86, 0x3e, 0x68, - 0x4a, 0x5e, 0x1e, 0x4b, 0xaa, 0xb8, 0x9f, 0x3a, // MerkleRoot - 0x32, 0x51, 0x8a, 0x88, 0xc3, 0x1b, 0xc8, 0x7f, - 0x61, 0x8f, 0x76, 0x67, 0x3e, 0x2c, 0xc7, 0x7a, - 0xb2, 0x12, 0x7b, 0x7a, 0xfd, 0xed, 0xa3, 0x3b, - 0x09, 0x3B, 0xC7, 0xE3, 0x67, 0x11, 0x7B, 0x3C, // AcceptedIDMerkleRoot - 0x30, 0xC1, 0xF8, 0xFD, 0xD0, 0xD9, 0x72, 0x87, - 0x7F, 0x16, 0xC5, 0x96, 0x2E, 0x8B, 0xD9, 0x63, - 0x65, 0x9C, 0x79, 0x3C, 0xE3, 0x70, 0xD9, 0x5F, - 0x10, 0x3B, 0xC7, 0xE3, 0x67, 0x11, 0x7B, 0x3C, // UTXOCommitment - 0x30, 0xC1, 0xF8, 0xFD, 0xD0, 0xD9, 0x72, 0x87, - 0x7F, 0x16, 0xC5, 0x96, 0x2E, 0x8B, 0xD9, 0x63, - 0x65, 0x9C, 0x79, 0x3C, 0xE3, 0x70, 0xD9, 0x5F, - 0x61, 0xbc, 0x66, 0x49, 0x00, 0x00, 0x00, 0x00, // Timestamp - 0xff, 0xff, 0x00, 0x1d, // Bits - 0x01, 0xe3, 0x62, 0x99, 0x00, 0x00, 0x00, 0x00, // Fake Nonce. TODO: (Ori) Replace to a real nonce - 0x00, // TxnCount (0 for headers message) - } - - tests := []struct { - in *MsgHeaders // Message to encode - out *MsgHeaders // Expected decoded message - buf []byte // Wire encoding - pver uint32 // Protocol version for wire encoding - }{ - // Latest protocol version with no headers. - { - noHeaders, - noHeaders, - noHeadersEncoded, - ProtocolVersion, - }, - - // Latest protocol version with one header. - { - oneHeader, - oneHeader, - oneHeaderEncoded, - ProtocolVersion, - }, - } - - t.Logf("Running %d tests", len(tests)) - for i, test := range tests { - // Encode the message to wire format. - var buf bytes.Buffer - err := test.in.KaspaEncode(&buf, test.pver) - if err != nil { - t.Errorf("KaspaEncode #%d error %v", i, err) - continue - } - if !bytes.Equal(buf.Bytes(), test.buf) { - t.Errorf("KaspaEncode #%d\n got: %s want: %s", i, - spew.Sdump(buf.Bytes()), spew.Sdump(test.buf)) - continue - } - - // Decode the message from wire format. - var msg MsgHeaders - rbuf := bytes.NewReader(test.buf) - err = msg.KaspaDecode(rbuf, test.pver) - if err != nil { - t.Errorf("KaspaDecode #%d error %v", i, err) - continue - } - if !reflect.DeepEqual(&msg, test.out) { - t.Errorf("KaspaDecode #%d\n got: %s want: %s", i, - spew.Sdump(&msg), spew.Sdump(test.out)) - continue - } - } -} - -// TestHeadersWireErrors performs negative tests against wire encode and decode -// of MsgHeaders to confirm error paths work correctly. -func TestHeadersWireErrors(t *testing.T) { - pver := ProtocolVersion - wireErr := &MessageError{} - - hashes := []*daghash.Hash{mainnetGenesisHash, simnetGenesisHash} - hashMerkleRoot := blockOne.Header.HashMerkleRoot - acceptedIDMerkleRoot := blockOne.Header.AcceptedIDMerkleRoot - utxoCommitment := blockOne.Header.UTXOCommitment - bits := uint32(0x1d00ffff) - nonce := uint64(0x9962e301) - bh := NewBlockHeader(1, hashes, hashMerkleRoot, acceptedIDMerkleRoot, utxoCommitment, bits, nonce) - bh.Version = blockOne.Header.Version - bh.Timestamp = blockOne.Header.Timestamp - - // Headers message with one header. - oneHeader := NewMsgHeaders() - oneHeader.AddBlockHeader(bh) - oneHeaderEncoded := []byte{ - 0x01, // VarInt for number of headers. - 0x01, 0x00, 0x00, 0x00, // Version 1 - 0x02, // NumParentBlocks - 0x6f, 0xe2, 0x8c, 0x0a, 0xb6, 0xf1, 0xb3, 0x72, // mainnetGenesisHash - 0xc1, 0xa6, 0xa2, 0x46, 0xae, 0x63, 0xf7, 0x4f, - 0x93, 0x1e, 0x83, 0x65, 0xe1, 0x5a, 0x08, 0x9c, - 0x68, 0xd6, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xf6, 0x7a, 0xd7, 0x69, 0x5d, 0x9b, 0x66, 0x2a, // simnetGenesisHash - 0x72, 0xff, 0x3d, 0x8e, 0xdb, 0xbb, 0x2d, 0xe0, - 0xbf, 0xa6, 0x7b, 0x13, 0x97, 0x4b, 0xb9, 0x91, - 0x0d, 0x11, 0x6d, 0x5c, 0xbd, 0x86, 0x3e, 0x68, - 0x3b, 0xa3, 0xed, 0xfd, 0x7a, 0x7b, 0x12, 0xb2, // MerkleRoot - 0x7a, 0xc7, 0x2c, 0x3e, 0x67, 0x76, 0x8f, 0x61, - 0x7f, 0xc8, 0x1b, 0xc3, 0x88, 0x8a, 0x51, 0x32, - 0x3a, 0x9f, 0xb8, 0xaa, 0x4b, 0x1e, 0x5e, 0x4a, - 0x09, 0x3B, 0xC7, 0xE3, 0x67, 0x11, 0x7B, 0x3C, // AcceptedIDMerkleRoot - 0x30, 0xC1, 0xF8, 0xFD, 0xD0, 0xD9, 0x72, 0x87, - 0x7F, 0x16, 0xC5, 0x96, 0x2E, 0x8B, 0xD9, 0x63, - 0x65, 0x9C, 0x79, 0x3C, 0xE3, 0x70, 0xD9, 0x5F, - 0x10, 0x3B, 0xC7, 0xE3, 0x67, 0x11, 0x7B, 0x3C, // UTXOCommitment - 0x30, 0xC1, 0xF8, 0xFD, 0xD0, 0xD9, 0x72, 0x87, - 0x7F, 0x16, 0xC5, 0x96, 0x2E, 0x8B, 0xD9, 0x63, - 0x65, 0x9C, 0x79, 0x3C, 0xE3, 0x70, 0xD9, 0x5F, - 0x61, 0xbc, 0x66, 0x49, 0x00, 0x00, 0x00, 0x00, // Timestamp - 0xff, 0xff, 0x00, 0x1d, // Bits - 0x01, 0xe3, 0x62, 0x99, 0x00, 0x00, 0x00, 0x00, // Fake Nonce. TODO: (Ori) Replace to a real nonce - 0x00, // TxnCount (0 for headers message) - } - - // Message that forces an error by having more than the max allowed - // headers. - maxHeaders := NewMsgHeaders() - for i := 0; i < MaxBlockHeadersPerMsg; i++ { - maxHeaders.AddBlockHeader(bh) - } - maxHeaders.Headers = append(maxHeaders.Headers, bh) - maxHeadersEncoded := []byte{ - 0xfd, 0xd1, 0x07, // Varint for number of addresses (2001)7D1 - } - - // Intentionally invalid block header that has a transaction count used - // to force errors. - bhTrans := NewBlockHeader(1, hashes, hashMerkleRoot, acceptedIDMerkleRoot, utxoCommitment, bits, nonce) - bhTrans.Version = blockOne.Header.Version - bhTrans.Timestamp = blockOne.Header.Timestamp - - transHeader := NewMsgHeaders() - transHeader.AddBlockHeader(bhTrans) - transHeaderEncoded := []byte{ - 0x01, // VarInt for number of headers. - 0x01, 0x00, 0x00, 0x00, // Version 1 - 0x02, // NumParentBlocks - 0x6f, 0xe2, 0x8c, 0x0a, 0xb6, 0xf1, 0xb3, 0x72, // mainnetGenesisHash - 0xc1, 0xa6, 0xa2, 0x46, 0xae, 0x63, 0xf7, 0x4f, - 0x93, 0x1e, 0x83, 0x65, 0xe1, 0x5a, 0x08, 0x9c, - 0x68, 0xd6, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xf6, 0x7a, 0xd7, 0x69, 0x5d, 0x9b, 0x66, 0x2a, // simnetGenesisHash - 0x72, 0xff, 0x3d, 0x8e, 0xdb, 0xbb, 0x2d, 0xe0, - 0xbf, 0xa6, 0x7b, 0x13, 0x97, 0x4b, 0xb9, 0x91, - 0x0d, 0x11, 0x6d, 0x5c, 0xbd, 0x86, 0x3e, 0x68, - 0x3b, 0xa3, 0xed, 0xfd, 0x7a, 0x7b, 0x12, 0xb2, // HashMerkleRoot - 0x7a, 0xc7, 0x2c, 0x3e, 0x67, 0x76, 0x8f, 0x61, - 0x7f, 0xc8, 0x1b, 0xc3, 0x88, 0x8a, 0x51, 0x32, - 0x3a, 0x9f, 0xb8, 0xaa, 0x4b, 0x1e, 0x5e, 0x4a, - 0x09, 0x3B, 0xC7, 0xE3, 0x67, 0x11, 0x7B, 0x3C, // AcceptedIDMerkleRoot - 0x30, 0xC1, 0xF8, 0xFD, 0xD0, 0xD9, 0x72, 0x87, - 0x7F, 0x16, 0xC5, 0x96, 0x2E, 0x8B, 0xD9, 0x63, - 0x65, 0x9C, 0x79, 0x3C, 0xE3, 0x70, 0xD9, 0x5F, - 0x10, 0x3B, 0xC7, 0xE3, 0x67, 0x11, 0x7B, 0x3C, // UTXOCommitment - 0x30, 0xC1, 0xF8, 0xFD, 0xD0, 0xD9, 0x72, 0x87, - 0x7F, 0x16, 0xC5, 0x96, 0x2E, 0x8B, 0xD9, 0x63, - 0x65, 0x9C, 0x79, 0x3C, 0xE3, 0x70, 0xD9, 0x5F, - 0x61, 0xbc, 0x66, 0x49, 0x00, 0x00, 0x00, 0x00, // Timestamp - 0xff, 0xff, 0x00, 0x1d, // Bits - 0x01, 0xe3, 0x62, 0x99, 0x00, 0x00, 0x00, 0x00, // Fake Nonce. TODO: (Ori) Replace to a real nonce - 0x01, // TxnCount (should be 0 for headers message, but 1 to force error) - } - - tests := []struct { - in *MsgHeaders // Value to encode - buf []byte // Wire encoding - pver uint32 // Protocol version for wire encoding - max int // Max size of fixed buffer to induce errors - writeErr error // Expected write error - readErr error // Expected read error - }{ - // Latest protocol version with intentional read/write errors. - // Force error in header count. - {oneHeader, oneHeaderEncoded, pver, 0, io.ErrShortWrite, io.EOF}, - // Force error in block header. - {oneHeader, oneHeaderEncoded, pver, 5, io.ErrShortWrite, io.EOF}, - // Force error with greater than max headers. - {maxHeaders, maxHeadersEncoded, pver, 3, wireErr, wireErr}, - // Force error with number of transactions. - {transHeader, transHeaderEncoded, pver, 178, io.ErrShortWrite, io.EOF}, - // Force error with included transactions. - {transHeader, transHeaderEncoded, pver, len(transHeaderEncoded), nil, wireErr}, - } - - t.Logf("Running %d tests", len(tests)) - for i, test := range tests { - // Encode to wire format. - w := newFixedWriter(test.max) - err := test.in.KaspaEncode(w, test.pver) - if reflect.TypeOf(err) != reflect.TypeOf(test.writeErr) { - t.Errorf("KaspaEncode #%d wrong error got: %v, want: %v", - i, err, test.writeErr) - continue - } - - // For errors which are not of type MessageError, check them for - // equality. - if msgErr := &(MessageError{}); !errors.As(err, &msgErr) { - if err != test.writeErr { - t.Errorf("KaspaEncode #%d wrong error got: %v, "+ - "want: %v", i, err, test.writeErr) - continue - } - } - - // Decode from wire format. - var msg MsgHeaders - r := newFixedReader(test.max, test.buf) - err = msg.KaspaDecode(r, test.pver) - if reflect.TypeOf(err) != reflect.TypeOf(test.readErr) { - t.Errorf("KaspaDecode #%d wrong error got: %v, want: %v", - i, err, test.readErr) - continue - } - - // For errors which are not of type MessageError, check them for - // equality. - if msgErr := &(MessageError{}); !errors.As(err, &msgErr) { - if err != test.readErr { - t.Errorf("KaspaDecode #%d wrong error got: %v, "+ - "want: %v", i, err, test.readErr) - continue - } - } - - } -} diff --git a/wire/msgsendheaders.go b/wire/msgsendheaders.go deleted file mode 100644 index 4b147ef98..000000000 --- a/wire/msgsendheaders.go +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright (c) 2016 The btcsuite developers -// Use of this source code is governed by an ISC -// license that can be found in the LICENSE file. - -package wire - -import ( - "io" -) - -// MsgSendHeaders implements the Message interface and represents a kaspa -// sendheaders message. It is used to request the peer send block headers -// rather than inventory vectors. -// -// This message has no payload. -type MsgSendHeaders struct{} - -// KaspaDecode decodes r using the kaspa protocol encoding into the receiver. -// This is part of the Message interface implementation. -func (msg *MsgSendHeaders) KaspaDecode(r io.Reader, pver uint32) error { - return nil -} - -// KaspaEncode encodes the receiver to w using the kaspa protocol encoding. -// This is part of the Message interface implementation. -func (msg *MsgSendHeaders) KaspaEncode(w io.Writer, pver uint32) error { - return nil -} - -// Command returns the protocol command string for the message. This is part -// of the Message interface implementation. -func (msg *MsgSendHeaders) Command() string { - return CmdSendHeaders -} - -// MaxPayloadLength returns the maximum length the payload can be for the -// receiver. This is part of the Message interface implementation. -func (msg *MsgSendHeaders) MaxPayloadLength(pver uint32) uint32 { - return 0 -} - -// NewMsgSendHeaders returns a new kaspa sendheaders message that conforms to -// the Message interface. See MsgSendHeaders for details. -func NewMsgSendHeaders() *MsgSendHeaders { - return &MsgSendHeaders{} -} diff --git a/wire/msgsendheaders_test.go b/wire/msgsendheaders_test.go deleted file mode 100644 index 6342bd5e3..000000000 --- a/wire/msgsendheaders_test.go +++ /dev/null @@ -1,118 +0,0 @@ -// Copyright (c) 2016 The btcsuite developers -// Use of this source code is governed by an ISC -// license that can be found in the LICENSE file. - -package wire - -import ( - "bytes" - "reflect" - "testing" - - "github.com/davecgh/go-spew/spew" -) - -// TestSendHeaders tests the MsgSendHeaders API against the latest protocol -// version. -func TestSendHeaders(t *testing.T) { - pver := ProtocolVersion - - // Ensure the command is expected value. - wantCmd := "sendheaders" - msg := NewMsgSendHeaders() - if cmd := msg.Command(); cmd != wantCmd { - t.Errorf("NewMsgSendHeaders: wrong command - got %v want %v", - cmd, wantCmd) - } - - // Ensure max payload is expected value. - wantPayload := uint32(0) - maxPayload := msg.MaxPayloadLength(pver) - if maxPayload != wantPayload { - t.Errorf("MaxPayloadLength: wrong max payload length for "+ - "protocol version %d - got %v, want %v", pver, - maxPayload, wantPayload) - } - - // Test encode with latest protocol version. - var buf bytes.Buffer - err := msg.KaspaEncode(&buf, pver) - if err != nil { - t.Errorf("encode of MsgSendHeaders failed %v err <%v>", msg, - err) - } - - // Test decode with latest protocol version. - readmsg := NewMsgSendHeaders() - err = readmsg.KaspaDecode(&buf, pver) - if err != nil { - t.Errorf("decode of MsgSendHeaders failed [%v] err <%v>", buf, - err) - } -} - -// TestSendHeadersCrossProtocol tests the MsgSendHeaders API when encoding with -// the latest protocol version and decoding with SendHeadersVersion. -func TestSendHeadersCrossProtocol(t *testing.T) { - msg := NewMsgSendHeaders() - - // Encode with latest protocol version. - var buf bytes.Buffer - err := msg.KaspaEncode(&buf, ProtocolVersion) - if err != nil { - t.Errorf("encode of MsgSendHeaders failed %v err <%v>", msg, - err) - } -} - -// TestSendHeadersWire tests the MsgSendHeaders wire encode and decode for -// various protocol versions. -func TestSendHeadersWire(t *testing.T) { - msgSendHeaders := NewMsgSendHeaders() - msgSendHeadersEncoded := []byte{} - - tests := []struct { - in *MsgSendHeaders // Message to encode - out *MsgSendHeaders // Expected decoded message - buf []byte // Wire encoding - pver uint32 // Protocol version for wire encoding - }{ - // Latest protocol version. - { - msgSendHeaders, - msgSendHeaders, - msgSendHeadersEncoded, - ProtocolVersion, - }, - } - - t.Logf("Running %d tests", len(tests)) - for i, test := range tests { - // Encode the message to wire format. - var buf bytes.Buffer - err := test.in.KaspaEncode(&buf, test.pver) - if err != nil { - t.Errorf("KaspaEncode #%d error %v", i, err) - continue - } - if !bytes.Equal(buf.Bytes(), test.buf) { - t.Errorf("KaspaEncode #%d\n got: %s want: %s", i, - spew.Sdump(buf.Bytes()), spew.Sdump(test.buf)) - continue - } - - // Decode the message from wire format. - var msg MsgSendHeaders - rbuf := bytes.NewReader(test.buf) - err = msg.KaspaDecode(rbuf, test.pver) - if err != nil { - t.Errorf("KaspaDecode #%d error %v", i, err) - continue - } - if !reflect.DeepEqual(&msg, test.out) { - t.Errorf("KaspaDecode #%d\n got: %s want: %s", i, - spew.Sdump(msg), spew.Sdump(test.out)) - continue - } - } -}