Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

multi: Expose disablerelaytx #2348

Merged
merged 1 commit into from
Apr 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions config.go
Original file line number Diff line number Diff line change
Expand Up @@ -148,8 +148,9 @@ type config struct {
Offline bool `long:"offline" description:"Do not sync the wallet"`

// SPV options
SPV bool `long:"spv" description:"Sync using simplified payment verification"`
SPVConnect []string `long:"spvconnect" description:"SPV sync only with specified peers; disables DNS seeding"`
SPV bool `long:"spv" description:"Sync using simplified payment verification"`
SPVConnect []string `long:"spvconnect" description:"SPV sync only with specified peers; disables DNS seeding"`
SPVDisableRelayTx bool `long:"spvdisablerelaytx" description:"Disable receiving mempool transactions when in SPV mode"`

// RPC server options
RPCCert *cfgutil.ExplicitString `long:"rpccert" description:"RPC server TLS certificate"`
Expand Down
1 change: 1 addition & 0 deletions dcrwallet.go
Original file line number Diff line number Diff line change
Expand Up @@ -546,6 +546,7 @@ func spvLoop(ctx context.Context, w *wallet.Wallet) {
amgr := addrmgr.New(amgrDir, cfg.lookup)
lp := p2p.NewLocalPeer(w.ChainParams(), addr, amgr)
lp.SetDialFunc(cfg.dial)
lp.SetDisableRelayTx(cfg.SPVDisableRelayTx)
syncer := spv.NewSyncer(w, lp)
if len(cfg.SPVConnect) > 0 {
syncer.SetPersistentPeers(cfg.SPVConnect)
Expand Down
53 changes: 47 additions & 6 deletions p2p/peering.go
Original file line number Diff line number Diff line change
Expand Up @@ -133,9 +133,10 @@ type LocalPeer struct {
announcedHeaders chan *inMsg
receivedInitState chan *inMsg

extaddr net.Addr
amgr *addrmgr.AddrManager
chainParams *chaincfg.Params
extaddr net.Addr
amgr *addrmgr.AddrManager
chainParams *chaincfg.Params
disableRelayTx bool

rpByID map[uint64]*RemotePeer
rpMu sync.Mutex
Expand Down Expand Up @@ -168,6 +169,13 @@ func (lp *LocalPeer) SetDialFunc(dial DialFunc) {
lp.dial = dial
}

// SetDisableRelayTx sets whether remote peers will be asked to relay
// transactions to the local peer. This must be called before the local peer
// runs.
func (lp *LocalPeer) SetDisableRelayTx(disableRelayTx bool) {
lp.disableRelayTx = disableRelayTx
}

func isCGNAT(ip net.IP) bool {
if ip4 := ip.To4(); ip4 != nil {
return ip4[0] == 100 && ip4[1]&0xc0 == 64 // 100.64.0.0/10
Expand Down Expand Up @@ -210,6 +218,7 @@ func (lp *LocalPeer) newMsgVersion(pver uint32, c net.Conn) (*wire.MsgVersion, e
v := wire.NewMsgVersion(la, ra, nonce, 0)
v.AddUserAgent(uaName, uaVersion)
v.ProtocolVersion = int32(pver)
v.DisableRelayTx = lp.disableRelayTx
return v, nil
}

Expand Down Expand Up @@ -738,9 +747,7 @@ func (rp *RemotePeer) readMessages(ctx context.Context) error {
case *wire.MsgHeaders:
rp.receivedHeaders(ctx, m)
case *wire.MsgInv:
if rp.lp.messageIsMasked(MaskInv) {
rp.lp.receivedInv <- newInMsg(rp, msg)
}
rp.receivedInv(ctx, m)
case *wire.MsgGetMiningState:
rp.receivedGetMiningState(ctx)
case *wire.MsgGetInitState:
Expand Down Expand Up @@ -1847,3 +1854,37 @@ func (rp *RemotePeer) GetInitState(ctx context.Context, msg *wire.MsgGetInitStat
}
}
}

// invVecContainsTx returns true if at least one inv vector is of type
// transaction.
func invVecContainsTx(inv []*wire.InvVect) bool {
for i := range inv {
if inv[i].Type == wire.InvTypeTx {
return true
}
}
return false
}

// receivedInv is called when an inv message is received from the remote peer.
func (rp *RemotePeer) receivedInv(ctx context.Context, inv *wire.MsgInv) {
const opf = "remotepeer(%v).receivedInv"

// When tx relay is disabled, we don't expect transactions on invs.
if rp.lp.disableRelayTx && invVecContainsTx(inv.InvList) {
op := errors.Opf(opf, rp.raddr)
err := errors.E(op, errors.Protocol, "received tx in msginv when tx relaying is disabled")
rp.Disconnect(err)
return
}

// Ignore if the user is not interested in invs.
if !rp.lp.messageIsMasked(MaskInv) {
return
}

select {
case rp.lp.receivedInv <- newInMsg(rp, inv):
case <-ctx.Done():
}
}
18 changes: 18 additions & 0 deletions sample-dcrwallet.conf
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,24 @@
; dcrdpassword=


; ------------------------------------------------------------------------------
; SPV settings
; ------------------------------------------------------------------------------

; Enable SPV mode by setting SPV to 1.
; spv=1

; spvconnect may be used to specify specific peers to connect to, when using
; SPV mode. Multiple peers may be specified. When spvconnect is set, the wallet
; will connect _only_ to the listed peers.
; spvconnect=

; Set spvdisablerelaytx to 1 to disable receiving transactions from remote peers
; in SPV mode. This reduces bandwidth consumption but effectively disables the
; mempool.
; spvdisablerelaytx=1


; ------------------------------------------------------------------------------
; Debug
; ------------------------------------------------------------------------------
Expand Down
Loading