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
client/asset/btc: Identify unknown transactions #2723
base: master
Are you sure you want to change the base?
Conversation
client/asset/btc/btc.go
Outdated
btc.tipMtx.Lock() | ||
tip := btc.currentTip | ||
btc.tipMtx.Unlock() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can be a read lock.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Decred rpc history too?
client/asset/bch/spv.go
Outdated
func (w *bchSPVWallet) GetTransactions(startBlock, endBlock int32, _ string, cancel <-chan struct{}) (*btcwallet.GetTransactionsResult, error) { | ||
startID := wallet.NewBlockIdentifierFromHeight(startBlock) | ||
endID := wallet.NewBlockIdentifierFromHeight(endBlock) | ||
ltcGTR, err := w.Wallet.GetTransactions(startID, endID, cancel) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
bchGTR
// We use GetTransactions instead of ListSinceBlock, because ListSinceBlock | ||
// does not include transactions that pay to a change address, which | ||
// Redeem, Refund, and RedeemBond do. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oooohhh. Nice catch.
client/asset/btc/txdb.go
Outdated
return nil, err | ||
} | ||
|
||
ctx, die := context.WithCancel(context.Background()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's pass in a context.Context
to the constructor.
client/asset/btc/txdb.go
Outdated
seq *badger.Sequence | ||
|
||
running atomic.Bool | ||
wg *sync.WaitGroup |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Make this a value and you don't have to initialize it.
client/asset/btc/txdb.go
Outdated
time.Sleep(10 * time.Millisecond) | ||
} | ||
|
||
return err |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can never be anything but nil
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It could be badger.ErrConflict
if we got conflicts 10 times.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh yeah
client/asset/btc/wallettypes.go
Outdated
@@ -149,3 +164,7 @@ type listDescriptorsResult struct { | |||
Next int64 `json:"next"` // next index to addresses generation; only set for ranged descriptors | |||
} `json:"descriptors"` | |||
} | |||
|
|||
type listTransactionsResult struct { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you're only using this struct in one place, you can define it there.
client/asset/dcr/dcr.go
Outdated
var dbPath string | ||
if spvWallet, ok := dcr.wallet.(*spvWallet); ok { | ||
initialAddress, err := spvWallet.InitialAddress(ctx) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
dbPath = dcr.txHistoryDBPath(initialAddress) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Type assertion is fine, but using an interface is cooler and more flexible imo.
var dbPath string
if initialAddresser, is := dcr.wallet.(interface {
InitialAddress(ctx context.Context) (string, error)
}); is {
initialAddress, err := initialAddresser.InitialAddress(ctx)
if err != nil {
return err
}
dbPath = dcr.txHistoryDBPath(initialAddress)
}
client/asset/dcr/dcr.go
Outdated
dcr.subprocessWg.Add(1) | ||
go func() { | ||
defer dcr.subprocessWg.Done() | ||
dcr.checkPendingTxs(ctx, uint64(newTipHeight)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need to sequence calls to checkPendingTxs
?
@@ -2529,6 +2534,12 @@ export default class WalletsPage extends BasePage { | |||
if (n.assetID === this.selectedAssetID) this.handleTxNote(n.transaction, n.new) | |||
break | |||
} | |||
case 'transactionHistorySynced' | |||
: { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
New line is accident?
client/asset/dcr/dcr.go
Outdated
@@ -901,6 +902,125 @@ func (dcr *ExchangeWallet) Info() *asset.WalletInfo { | |||
// } | |||
// } | |||
|
|||
func (dcr *ExchangeWallet) txHistoryDBPath(walletID string) string { | |||
return filepath.Join(dcr.walletDir, fmt.Sprintf("txhistory-%s.db", walletID)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If it's a directory, should drop the file extension.
@buck54321 This PR comes on top of #2693. For this one I was only going to do identifying BTC transactions, then I'll add another PR for DCR later. Let's merge #2693 first, then I'll rebase this one. |
ebf36db
to
b4c1c96
Compare
This diff updates the btc wallet to identify all past transactions that the wallet has made. This way, if dexc is reinitalized with a seed that was already used, the transaction history of native wallets can be recovered. When an RPC wallet is connected, the transaction history prior to connecting will be displayed. The SPV wallet uses the `GetTransactions` method to retrieve unknown transactions rather than `ListSinceBlock` as was previously used to get incoming transactions. This is because `ListSinceBlock` does not include incoming transactions that pay to a change address, which is done by redemption and refund transactions. The RPC wallet continues to use the listsinceblock RPC call. During initial syncing of the transaction history, the wallet does not send notifications to the front end each time it discovers a new transaction. Instead, a notification that the syncing has complete is sent to the front end. Co-authored-by: buck54321 <buck54321@gmail.com>
Comes on top of #2693 and builds on #2694