Skip to content

Commit

Permalink
Upgrade spv module to dcrwallet v1.6.0-rc4
Browse files Browse the repository at this point in the history
  • Loading branch information
beansgum committed Nov 30, 2020
1 parent fc4f2e5 commit e63f7a1
Show file tree
Hide file tree
Showing 6 changed files with 76 additions and 49 deletions.
16 changes: 14 additions & 2 deletions accounts.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ import (
"github.com/planetdecred/dcrlibwallet/addresshelper"
)

const AddressGapLimit uint32 = 20

func (wallet *Wallet) GetAccounts() (string, error) {
accountsResponse, err := wallet.GetAccountsRaw()
if err != nil {
Expand All @@ -29,14 +31,24 @@ func (wallet *Wallet) GetAccountsRaw() (*Accounts, error) {
if err != nil {
return nil, err
}

accounts := make([]*Account, len(resp.Accounts))
for i, a := range resp.Accounts {
account, err := wallet.GetAccount(int32(a.AccountNumber))
balance, err := wallet.GetAccountBalance(int32(a.AccountNumber))
if err != nil {
return nil, err
}

accounts[i] = account
accounts[i] = &Account{
WalletID: wallet.ID,
Number: int32(a.AccountNumber),
Name: a.AccountName,
Balance: balance,
TotalBalance: int64(a.TotalBalance),
ExternalKeyCount: int32(a.LastUsedExternalIndex + AddressGapLimit), // Add gap limit
InternalKeyCount: int32(a.LastUsedInternalIndex + AddressGapLimit),
ImportedKeyCount: int32(a.ImportedKeyCount),
}
}

return &Accounts{
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,6 @@ require (
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect
)

replace decred.org/dcrwallet => decred.org/dcrwallet v1.6.0-rc3
replace decred.org/dcrwallet => decred.org/dcrwallet v1.6.0-rc4

go 1.13
5 changes: 5 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ decred.org/cspp v0.3.0 h1:2AkSsWzA7HIMZImfw0gT82Gdp8OXIM4NsBn7vna22uE=
decred.org/cspp v0.3.0/go.mod h1:UygjYilC94dER3BEU65Zzyoqy9ngJfWCD2rdJqvUs2A=
decred.org/dcrwallet v1.6.0-rc3 h1:Dft0ArM2hpqbjyYdhPEBbsTPah19Kno1Aa5WI5n4zn0=
decred.org/dcrwallet v1.6.0-rc3/go.mod h1:KfDFVvtUnyCKPp6WwWxgD5Q5nlcgvd826tVOHyPOBU0=
decred.org/dcrwallet v1.6.0-rc4 h1:5IT6mFa+2YMqenu6aE2LetD0N8QSUVFyAFl205PvIIE=
decred.org/dcrwallet v1.6.0-rc4/go.mod h1:lsrNbuKxkPGeHXPufxNTckwQopCEDz0r3t0a8JCKAmU=
github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9 h1:HD8gA2tkByhMAwYaFAX9w2l7vxvBQ5NMoxDrkhqhtn4=
github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
Expand Down Expand Up @@ -43,6 +45,7 @@ github.com/decred/dcrd/blockchain/standalone/v2 v2.0.0 h1:9gUuH0u/IZNPWBK9K3CxgA
github.com/decred/dcrd/blockchain/standalone/v2 v2.0.0/go.mod h1:t2qaZ3hNnxHZ5kzVJDgW5sp47/8T5hYJt7SR+/JtRhI=
github.com/decred/dcrd/blockchain/v3 v3.0.1 h1:Sk1Td+2uahykZFMUunhhL0gBNawosVNBoq034Bjw6EQ=
github.com/decred/dcrd/blockchain/v3 v3.0.1/go.mod h1:LD5VA95qdb+DlRiPI8VLBimDqvlDCAJsidZ5oD6nc/U=
github.com/decred/dcrd/blockchain/v3 v3.0.2/go.mod h1:LD5VA95qdb+DlRiPI8VLBimDqvlDCAJsidZ5oD6nc/U=
github.com/decred/dcrd/certgen v1.1.1/go.mod h1:ivkPLChfjdAgFh7ZQOtl6kJRqVkfrCq67dlq3AbZBQE=
github.com/decred/dcrd/chaincfg/chainhash v1.0.2 h1:rt5Vlq/jM3ZawwiacWjPa+smINyLRN07EO0cNBV6DGU=
github.com/decred/dcrd/chaincfg/chainhash v1.0.2/go.mod h1:BpbrGgrPTr3YJYRN3Bm+D9NuaFd+zGyNeIKgrhCXK60=
Expand Down Expand Up @@ -93,6 +96,8 @@ github.com/decred/dcrd/rpc/jsonrpc/types/v2 v2.0.0 h1:uyvwjO+90KHxZIIztobB9cG+qV
github.com/decred/dcrd/rpc/jsonrpc/types/v2 v2.0.0/go.mod h1:c5S+PtQWNIA2aUakgrLhrlopkMadcOv51dWhCEdo49c=
github.com/decred/dcrd/rpc/jsonrpc/types/v2 v2.2.0 h1:8xxN/nKOO2yx29oZEL8METscZ3eJnvbl68oFiNg2+SI=
github.com/decred/dcrd/rpc/jsonrpc/types/v2 v2.2.0/go.mod h1:krn89ZOgSa8yc7sA4WpDK95p61NnjNWFkNlMnGrKbMc=
github.com/decred/dcrd/rpc/jsonrpc/types/v2 v2.3.0 h1:KZ2zihwY5Mx6EeYwEA3bL3k+qDXdCraQL+iDIG1BP5k=
github.com/decred/dcrd/rpc/jsonrpc/types/v2 v2.3.0/go.mod h1:krn89ZOgSa8yc7sA4WpDK95p61NnjNWFkNlMnGrKbMc=
github.com/decred/dcrd/rpcclient/v5 v5.0.0 h1:dQAPuZU9D+/CP8DcyVjtNxLjT4Ew+L6QhYd/MWhSFvw=
github.com/decred/dcrd/rpcclient/v5 v5.0.0/go.mod h1:lg7e2kpulSpynHkS2JXJ+trQ4PWHaHLQcp/Q0eSIvBc=
github.com/decred/dcrd/txscript/v2 v2.1.0 h1:IKIpNm0lPmNQoaZ2zxZm1qMwfmLb/XXeahxXlfc+MrA=
Expand Down
13 changes: 0 additions & 13 deletions multiwallet_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import (
"github.com/asdine/storm"
"github.com/kevinburke/nacl"
"github.com/kevinburke/nacl/secretbox"
"github.com/planetdecred/dcrlibwallet/spv"
"golang.org/x/crypto/scrypt"
)

Expand Down Expand Up @@ -87,18 +86,6 @@ func (mw *MultiWallet) markWalletAsDiscoveredAccounts(walletID int) error {
return nil
}

func (mw *MultiWallet) setNetworkBackend(syncer *spv.Syncer) {
for walletID, wallet := range mw.wallets {
if wallet.WalletOpened() {
walletBackend := &spv.WalletBackend{
Syncer: syncer,
WalletID: walletID,
}
wallet.internal.SetNetworkBackend(walletBackend)
}
}
}

// RootDirFileSizeInBytes returns the total directory size of
// multiwallet's root directory in bytes.
func (mw *MultiWallet) RootDirFileSizeInBytes() (int64, error) {
Expand Down
78 changes: 56 additions & 22 deletions spv/sync.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"decred.org/dcrwallet/validate"
"decred.org/dcrwallet/wallet"
"github.com/decred/dcrd/addrmgr"
"github.com/decred/dcrd/blockchain/stake/v3"
"github.com/decred/dcrd/chaincfg/chainhash"
"github.com/decred/dcrd/gcs/v2/blockcf2"
"github.com/decred/dcrd/wire"
Expand All @@ -28,7 +29,7 @@ import (
// reqSvcs defines the services that must be supported by outbounded peers.
// After fetching more addresses (if needed), peers are disconnected from if
// they do not provide each of these services.
const reqSvcs = wire.SFNodeNetwork | wire.SFNodeCF
const reqSvcs = wire.SFNodeNetwork

// Syncer implements wallet synchronization services by over the Decred wire
// protocol using Simplified Payment Verification (SPV) with compact filters.
Expand Down Expand Up @@ -276,6 +277,17 @@ func (s *Syncer) tipChanged(tip *wire.BlockHeader, reorgDepth int32, matchingTxs
}
}

// setRequiredHeight sets the required height a peer must advertise as their
// last height. Initial height 6 blocks below the current chain tip height
// result in a handshake error.
func (s *Syncer) setRequiredHeight(tipHeight int32) {
requireHeight := tipHeight
if requireHeight > 6 {
requireHeight -= 6
}
s.lp.RequirePeerHeight(requireHeight)
}

func (s *Syncer) lowestChainTip(ctx context.Context) (chainhash.Hash, int32, *wallet.Wallet) {
var lowestTip int32 = -1
var lowestTipHash chainhash.Hash
Expand Down Expand Up @@ -311,10 +323,15 @@ func (s *Syncer) highestChainTip(ctx context.Context) (chainhash.Hash, int32, *w
func (s *Syncer) Run(ctx context.Context) error {
log.Infof("Syncing %d wallets", len(s.wallets))

var highestTipHeight int32
for id, w := range s.wallets {
tipHash, tipHeight := w.MainChainTip(ctx)
log.Infof("[%d] Headers synced through block %v height %d", id, &tipHash, tipHeight)

if tipHeight > highestTipHeight {
highestTipHeight = tipHeight
}

rescanPoint, err := w.RescanPoint(ctx)
if err != nil {
return err
Expand All @@ -331,6 +348,7 @@ func (s *Syncer) Run(ctx context.Context) error {
log.Infof("[%d] Transactions synced through block %v height %d", id, &tipHash, tipHeight)
}
}
s.setRequiredHeight(highestTipHeight)

_, _, lowestChainWallet := s.lowestChainTip(ctx)
locators, err := lowestChainWallet.BlockLocators(ctx, nil)
Expand Down Expand Up @@ -370,10 +388,23 @@ func (s *Syncer) Run(ctx context.Context) error {

g.Go(func() error { return s.handleMempool(ctx) })

for walletID, w := range s.wallets {
walletBackend := &WalletBackend{
Syncer: s,
WalletID: walletID,
}

w.SetNetworkBackend(walletBackend)
defer w.SetNetworkBackend(nil)
}

// Wait until cancellation or a handler errors.
return g.Wait()
}

// peerCandidate returns a peer address that we shall attempt to connect to.
// Only peers not already remotes or in the process of connecting are returned.
// Any address returned is marked in s.connectingRemotes before returning.
func (s *Syncer) peerCandidate(svcs wire.ServiceFlag) (*wire.NetAddress, error) {
// Try to obtain peer candidates at random, decreasing the requirements
// as more tries are performed.
Expand All @@ -384,27 +415,28 @@ func (s *Syncer) peerCandidate(svcs wire.ServiceFlag) (*wire.NetAddress, error)
}
na := kaddr.NetAddress()

// Skip peer if already connected
// TODO: this should work with network blocks, not exact addresses.
k := addrmgr.NetAddressKey(na)
s.remotesMu.Lock()
_, isConnecting := s.connectingRemotes[k]
_, isRemote := s.remotes[k]
s.remotesMu.Unlock()
if isConnecting || isRemote {
continue
}

switch {
// Skip peer if already connected, or in process of connecting
// TODO: this should work with network blocks, not exact addresses.
case isConnecting || isRemote:
fallthrough
// Only allow recent nodes (10mins) after we failed 30 times
if tries < 30 && time.Since(kaddr.LastAttempt()) < 10*time.Minute {
continue
}

case tries < 30 && time.Since(kaddr.LastAttempt()) < 10*time.Minute:
fallthrough
// Skip peers without matching service flags for the first 50 tries.
if tries < 50 && kaddr.NetAddress().Services&svcs != svcs {
case tries < 50 && kaddr.NetAddress().Services&svcs != svcs:
s.remotesMu.Unlock()
continue
}

s.connectingRemotes[k] = struct{}{}
s.remotesMu.Unlock()

return na, nil
}
return nil, errors.New("no addresses")
Expand Down Expand Up @@ -501,10 +533,6 @@ func (s *Syncer) connectToCandidates(ctx context.Context) error {
raddr := net.JoinHostPort(na.IP.String(), port)
k := addrmgr.NetAddressKey(na)

s.remotesMu.Lock()
s.connectingRemotes[k] = struct{}{}
s.remotesMu.Unlock()

rp, err := s.lp.ConnectOutbound(ctx, raddr, reqSvcs)
if err != nil {
s.remotesMu.Lock()
Expand Down Expand Up @@ -841,6 +869,10 @@ ProcessTx:
for walletID, w := range s.wallets {
relevant := s.filterRelevant(txs, walletID)
for _, tx := range relevant {

if w.ManualTickets() && stake.IsSStx(tx) {
continue
}
err := w.AddTransaction(ctx, tx, nil)
if err != nil {
op := errors.Opf(opf, rp.RemoteAddr())
Expand Down Expand Up @@ -1022,7 +1054,7 @@ func (s *Syncer) handleBlockAnnouncements(ctx context.Context, rp *p2p.RemotePee
return err
}

for key, w := range s.wallets {
for walletID, w := range s.wallets {
newBlocks := make([]*wallet.BlockNode, 0, len(headers))
var bestChain []*wallet.BlockNode
var matchingTxs map[chainhash.Hash][]*wire.MsgTx
Expand Down Expand Up @@ -1074,7 +1106,7 @@ func (s *Syncer) handleBlockAnnouncements(ctx context.Context, rp *p2p.RemotePee
return err
}
if rpt == nil {
matchingTxs, err = s.scanChain(ctx, rp, bestChain, bmap, key)
matchingTxs, err = s.scanChain(ctx, rp, bestChain, bmap, walletID)
if err != nil {
return err
}
Expand All @@ -1086,12 +1118,14 @@ func (s *Syncer) handleBlockAnnouncements(ctx context.Context, rp *p2p.RemotePee
}
if len(prevChain) != 0 {
log.Infof("[%d] Reorganize from %v to %v (total %d block(s) reorged)",
key, prevChain[len(prevChain)-1].Hash, bestChain[len(bestChain)-1].Hash, len(prevChain))
walletID, prevChain[len(prevChain)-1].Hash, bestChain[len(bestChain)-1].Hash, len(prevChain))
for _, n := range prevChain {
s.sidechains.AddBlockNode(n)
}
}
s.tipChanged(bestChain[len(bestChain)-1].Header, int32(len(prevChain)), matchingTxs)
tipHeader := bestChain[len(bestChain)-1].Header
s.setRequiredHeight(int32(tipHeader.Height))
s.tipChanged(tipHeader, int32(len(prevChain)), matchingTxs)

return nil
}()
Expand All @@ -1109,7 +1143,7 @@ func (s *Syncer) handleBlockAnnouncements(ctx context.Context, rp *p2p.RemotePee
// Log connected blocks.
for _, n := range bestChain {
log.Infof("[%d] Connected block %v, height %d, %d wallet transaction(s)",
key, n.Hash, n.Header.Height, len(matchingTxs[*n.Hash]))
walletID, n.Hash, n.Header.Height, len(matchingTxs[*n.Hash]))
}
// Announced blocks not in the main chain are logged as sidechain or orphan
// blocks.
Expand All @@ -1121,7 +1155,7 @@ func (s *Syncer) handleBlockAnnouncements(ctx context.Context, rp *p2p.RemotePee
if haveBlock {
continue
}
log.Infof("[%d] Received sidechain or orphan block %v, height %v", key, n.Hash, n.Header.Height)
log.Infof("[%d] Received sidechain or orphan block %v, height %v", walletID, n.Hash, n.Header.Height)
}
}

Expand Down
11 changes: 0 additions & 11 deletions sync.go
Original file line number Diff line number Diff line change
Expand Up @@ -225,8 +225,6 @@ func (mw *MultiWallet) SpvSync() error {
syncer.SetPersistentPeers(validPeerAddresses)
}

mw.setNetworkBackend(syncer)

ctx, cancel := mw.contextWithShutdownCancel()

var restartSyncRequested bool
Expand Down Expand Up @@ -295,15 +293,6 @@ func (mw *MultiWallet) CancelSync() {

log.Info("Sync fully canceled.")
}

for _, libWallet := range mw.wallets {
loadedWallet, walletLoaded := libWallet.loader.LoadedWallet()
if !walletLoaded {
continue
}

loadedWallet.SetNetworkBackend(nil)
}
}

func (wallet *Wallet) IsWaiting() bool {
Expand Down

0 comments on commit e63f7a1

Please sign in to comment.