@@ -8,13 +8,11 @@ package netsync
88import (
99 "context"
1010 "errors"
11- "fmt"
1211 "math"
1312 "sync"
1413 "sync/atomic"
1514 "time"
1615
17- "github.com/decred/dcrd/blockchain/stake/v5"
1816 "github.com/decred/dcrd/chaincfg/chainhash"
1917 "github.com/decred/dcrd/chaincfg/v3"
2018 "github.com/decred/dcrd/container/apbf"
@@ -2062,116 +2060,63 @@ func (m *SyncManager) SyncPeerID() int32 {
20622060// the peer is not banned for sending unrequested data when it responds.
20632061//
20642062// This function is safe for concurrent access.
2065- func (m * SyncManager ) RequestFromPeer (peer * Peer , blocks , voteHashes ,
2066- tSpendHashes []chainhash.Hash ) error {
2067-
2063+ func (m * SyncManager ) RequestFromPeer (peer * Peer , blocks , voteHashes , tSpendHashes []chainhash.Hash ) {
20682064 if m .shutdownRequested () {
2069- return nil
2065+ return
20702066 }
20712067
20722068 defer m .requestMtx .Unlock ()
20732069 m .requestMtx .Lock ()
20742070
2075- // Add the blocks to the request.
2071+ // Request as many needed blocks as possible at once.
2072+ var numRequested uint32
20762073 gdMsg := wire .NewMsgGetData ()
20772074 for i := range blocks {
2078- // Skip the block when it has already been requested.
2079- bh := & blocks [i ]
2080- if m .isRequestedBlock (bh ) {
2081- continue
2082- }
2083-
2084- // Skip the block when it is already known.
2085- if m .cfg .Chain .HaveBlock (bh ) {
2075+ // Skip the block when it has already been requested or is already
2076+ // known.
2077+ blockHash := & blocks [i ]
2078+ if m .isRequestedBlock (blockHash ) || m .cfg .Chain .HaveBlock (blockHash ) {
20862079 continue
20872080 }
20882081
2089- err := gdMsg .AddInvVect (wire .NewInvVect (wire .InvTypeBlock , bh ))
2090- if err != nil {
2091- return fmt .Errorf ("unexpected error encountered building request " +
2092- "for block %v: %w" , bh , err )
2082+ gdMsg .AddInvVect (wire .NewInvVect (wire .InvTypeBlock , blockHash ))
2083+ m .requestedBlocks [* blockHash ] = peer
2084+ numRequested ++
2085+ if numRequested == wire .MaxInvPerMsg {
2086+ // Send full getdata message and reset.
2087+ peer .QueueMessage (gdMsg , nil )
2088+ gdMsg = wire .NewMsgGetData ()
2089+ numRequested = 0
20932090 }
2094-
2095- m .requestedBlocks [* bh ] = peer
20962091 }
20972092
2098- addTxsToRequest := func (hashes []chainhash.Hash , txType stake.TxType ) error {
2099- // Return immediately if txs is nil.
2100- if hashes == nil {
2101- return nil
2102- }
2103-
2093+ // Request as many needed votes and treasury spend transactions as possible
2094+ // at once.
2095+ for _ , hashes := range [][]chainhash.Hash {voteHashes , tSpendHashes } {
21042096 for i := range hashes {
2105- // Skip the transaction when it has already been requested.
2097+ // Skip the transaction when it has already been requested or is
2098+ // otherwise not needed.
21062099 txHash := & hashes [i ]
2107- if _ , ok := m .requestedTxns [* txHash ]; ok {
2108- continue
2109- }
2110-
2111- // Ask the transaction memory pool if the transaction is known
2112- // to it in any form (main pool or orphan).
2113- if m .cfg .TxMemPool .HaveTransaction (txHash ) {
2114- continue
2115- }
2116-
2117- // Check if the transaction exists from the point of view of the main
2118- // chain tip. Note that this is only a best effort since it is expensive
2119- // to check existence of every output and the only purpose of this check
2120- // is to avoid requesting already known transactions.
2121- //
2122- // Check for a specific outpoint based on the tx type.
2123- outpoint := wire.OutPoint {Hash : * txHash }
2124- switch txType {
2125- case stake .TxTypeSSGen :
2126- // The first two outputs of vote transactions are OP_RETURN <data>, and
2127- // therefore never exist as an unspent txo. Use the third output, as
2128- // the third output (and subsequent outputs) are OP_SSGEN outputs.
2129- outpoint .Index = 2
2130- outpoint .Tree = wire .TxTreeStake
2131- case stake .TxTypeTSpend :
2132- // The first output of a tSpend transaction is OP_RETURN <data>, and
2133- // therefore never exists as an unspent txo. Use the second output, as
2134- // the second output (and subsequent outputs) are OP_TGEN outputs.
2135- outpoint .Index = 1
2136- outpoint .Tree = wire .TxTreeStake
2137- }
2138- entry , err := m .cfg .Chain .FetchUtxoEntry (outpoint )
2139- if err != nil {
2140- return err
2141- }
2142- if entry != nil {
2100+ _ , alreadyRequested := m .requestedTxns [* txHash ]
2101+ if alreadyRequested || ! m .needTx (txHash ) {
21432102 continue
21442103 }
21452104
2146- err = gdMsg .AddInvVect (wire .NewInvVect (wire .InvTypeTx , txHash ))
2147- if err != nil {
2148- return fmt .Errorf ("unexpected error encountered building request " +
2149- "for tx %v: %w" , txHash , err )
2150- }
2151-
2105+ gdMsg .AddInvVect (wire .NewInvVect (wire .InvTypeTx , txHash ))
21522106 m .requestedTxns [* txHash ] = peer
2107+ numRequested ++
2108+ if numRequested == wire .MaxInvPerMsg {
2109+ // Send full getdata message and reset.
2110+ peer .QueueMessage (gdMsg , nil )
2111+ gdMsg = wire .NewMsgGetData ()
2112+ numRequested = 0
2113+ }
21532114 }
2154-
2155- return nil
2156- }
2157-
2158- // Add the vote transactions to the request.
2159- err := addTxsToRequest (voteHashes , stake .TxTypeSSGen )
2160- if err != nil {
2161- return err
2162- }
2163-
2164- // Add the tspend transactions to the request.
2165- err = addTxsToRequest (tSpendHashes , stake .TxTypeTSpend )
2166- if err != nil {
2167- return err
21682115 }
21692116
21702117 if len (gdMsg .InvList ) > 0 {
21712118 peer .QueueMessage (gdMsg , nil )
21722119 }
2173-
2174- return nil
21752120}
21762121
21772122// RequestMixMsgFromPeer requests the specified mix message from the given peer.
0 commit comments