Merge pull request #1896 from Roasbeef/btcwallet-unconf-txn

lnwallet+rpc: allow unconfirmed transactions to be returned over RPC, fix SubscribeTransaction unconf for neutrino
This commit is contained in:
Olaoluwa Osuntokun 2018-09-12 22:12:38 -07:00 committed by GitHub
commit 1c4bd04c55
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 89 additions and 14 deletions

5
Gopkg.lock generated
View file

@ -106,7 +106,7 @@
revision = "ab6388e0c60ae4834a1f57511e20c17b5f78be4b" revision = "ab6388e0c60ae4834a1f57511e20c17b5f78be4b"
[[projects]] [[projects]]
digest = "1:012039cbb6694894aa9e9890645e6ade8a5aff5a02c279714779eff3eae53bc2" digest = "1:e6575f3ee773e72a38319dbd8f4cb7f1b574eccfed7cb103c3a25c254d5c250f"
name = "github.com/btcsuite/btcwallet" name = "github.com/btcsuite/btcwallet"
packages = [ packages = [
"chain", "chain",
@ -126,7 +126,7 @@
"wtxmgr", "wtxmgr",
] ]
pruneopts = "UT" pruneopts = "UT"
revision = "f4ae41ce5f5834eb67ab64cdeed74c74fc95638c" revision = "421298df22601db0fe4adb8f4be71b7014324ba9"
[[projects]] [[projects]]
branch = "master" branch = "master"
@ -417,7 +417,6 @@
version = "v0.3.0" version = "v0.3.0"
[[projects]] [[projects]]
branch = "master"
digest = "1:c9e7a4b4d47c0ed205d257648b0e5b0440880cb728506e318f8ac7cd36270bc4" digest = "1:c9e7a4b4d47c0ed205d257648b0e5b0440880cb728506e318f8ac7cd36270bc4"
name = "golang.org/x/time" name = "golang.org/x/time"
packages = ["rate"] packages = ["rate"]

View file

@ -72,7 +72,7 @@
[[constraint]] [[constraint]]
name = "github.com/btcsuite/btcwallet" name = "github.com/btcsuite/btcwallet"
revision = "f4ae41ce5f5834eb67ab64cdeed74c74fc95638c" revision = "421298df22601db0fe4adb8f4be71b7014324ba9"
[[constraint]] [[constraint]]
name = "github.com/tv42/zbase32" name = "github.com/tv42/zbase32"

View file

@ -6,7 +6,6 @@ import (
"strings" "strings"
"sync" "sync"
"sync/atomic" "sync/atomic"
"time"
"github.com/btcsuite/btcd/btcjson" "github.com/btcsuite/btcd/btcjson"
"github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/btcsuite/btcd/chaincfg/chainhash"
@ -115,7 +114,7 @@ func New(chainConn *chain.BitcoindConn, spendHintCache chainntnfs.SpendHintCache
quit: make(chan struct{}), quit: make(chan struct{}),
} }
notifier.chainConn = chainConn.NewBitcoindClient(time.Unix(0, 0)) notifier.chainConn = chainConn.NewBitcoindClient()
return notifier return notifier
} }

View file

@ -335,7 +335,7 @@ func newChainControlFromConfig(cfg *config, chanDB *channeldb.DB,
bitcoindConn, hintCache, hintCache, bitcoindConn, hintCache, hintCache,
) )
cc.chainView = chainview.NewBitcoindFilteredChainView(bitcoindConn) cc.chainView = chainview.NewBitcoindFilteredChainView(bitcoindConn)
walletConfig.ChainSource = bitcoindConn.NewBitcoindClient(birthday) walletConfig.ChainSource = bitcoindConn.NewBitcoindClient()
// If we're not in regtest mode, then we'll attempt to use a // If we're not in regtest mode, then we'll attempt to use a
// proper fee estimator for testnet. // proper fee estimator for testnet.

View file

@ -559,9 +559,11 @@ func (b *BtcWallet) ListTransactionDetails() ([]*lnwallet.TransactionDetail, err
bestBlock := b.wallet.Manager.SyncedTo() bestBlock := b.wallet.Manager.SyncedTo()
currentHeight := bestBlock.Height currentHeight := bestBlock.Height
// TODO(roasbeef): can replace with start "wallet birthday" // We'll attempt to find all unconfirmed transactions (height of -1),
// as well as all transactions that are known to have confirmed at this
// height.
start := base.NewBlockIdentifierFromHeight(0) start := base.NewBlockIdentifierFromHeight(0)
stop := base.NewBlockIdentifierFromHeight(bestBlock.Height) stop := base.NewBlockIdentifierFromHeight(-1)
txns, err := b.wallet.GetTransactions(start, stop, nil) txns, err := b.wallet.GetTransactions(start, stop, nil)
if err != nil { if err != nil {
return nil, err return nil, err

View file

@ -1055,7 +1055,9 @@ func testListTransactionDetails(miner *rpctest.Harness,
delete(txids, txDetail.Hash) delete(txids, txDetail.Hash)
} }
if len(txids) != 0 { if len(txids) != 0 {
t.Fatalf("all transactions not found in details!") t.Fatalf("all transactions not found in details: left=%v, "+
"returned_set=%v", spew.Sdump(txids),
spew.Sdump(txDetails))
} }
// Next create a transaction paying to an output which isn't under the // Next create a transaction paying to an output which isn't under the
@ -1075,6 +1077,41 @@ func testListTransactionDetails(miner *rpctest.Harness,
if err != nil { if err != nil {
t.Fatalf("tx not relayed to miner: %v", err) t.Fatalf("tx not relayed to miner: %v", err)
} }
// Before we mine the next block, we'll ensure that the above
// transaction shows up in the set of unconfirmed transactions returned
// by ListTransactionDetails.
err = waitForWalletSync(miner, alice)
if err != nil {
t.Fatalf("Couldn't sync Alice's wallet: %v", err)
}
// We should be able to find the transaction above in the set of
// returned transactions, and it should have a confirmation of -1,
// indicating that it's not yet mined.
txDetails, err = alice.ListTransactionDetails()
if err != nil {
t.Fatalf("unable to fetch tx details: %v", err)
}
var mempoolTxFound bool
for _, txDetail := range txDetails {
if !bytes.Equal(txDetail.Hash[:], burnTXID[:]) {
continue
}
// Now that we've found the transaction, ensure that it has a
// negative number of confirmations to indicate that it's
// unconfirmed.
mempoolTxFound = true
if txDetail.NumConfirmations != 0 {
t.Fatalf("num confs incorrect, got %v expected %v",
txDetail.NumConfirmations, 0)
}
}
if !mempoolTxFound {
t.Fatalf("unable to find mempool tx in tx details!")
}
burnBlock, err := miner.Node.Generate(1) burnBlock, err := miner.Node.Generate(1)
if err != nil { if err != nil {
t.Fatalf("unable to mine block: %v", err) t.Fatalf("unable to mine block: %v", err)
@ -1233,6 +1270,45 @@ func testTransactionSubscriptions(miner *rpctest.Harness,
t.Fatalf("transactions not received after 5 seconds") t.Fatalf("transactions not received after 5 seconds")
case <-confirmedNtfns: // Fall through on success case <-confirmedNtfns: // Fall through on success
} }
// We'll also ensure that the client is able to send our new
// notifications when we _create_ transactions ourselves that spend our
// own outputs.
b := txscript.NewScriptBuilder()
b.AddOp(txscript.OP_0)
outputScript, err := b.Script()
if err != nil {
t.Fatalf("unable to make output script: %v", err)
}
burnOutput := wire.NewTxOut(outputAmt, outputScript)
txid, err := alice.SendOutputs([]*wire.TxOut{burnOutput}, 2500)
if err != nil {
t.Fatalf("unable to create burn tx: %v", err)
}
err = waitForMempoolTx(miner, txid)
if err != nil {
t.Fatalf("tx not relayed to miner: %v", err)
}
// Before we mine the next block, we'll ensure that the above
// transaction shows up in the set of unconfirmed transactions returned
// by ListTransactionDetails.
err = waitForWalletSync(miner, alice)
if err != nil {
t.Fatalf("Couldn't sync Alice's wallet: %v", err)
}
// As we just sent the transaction and it was landed in the mempool, we
// should get a notification for a new unconfirmed transactions
select {
case <-time.After(time.Second * 10):
t.Fatalf("transactions not received after 10 seconds")
case unConfTx := <-txClient.UnconfirmedTransactions():
if unConfTx.Hash != *txid {
t.Fatalf("wrong txn notified: expected %v got %v",
txid, unConfTx.Hash)
}
}
} }
// testPublishTransaction checks that PublishTransaction returns the // testPublishTransaction checks that PublishTransaction returns the
@ -2278,8 +2354,8 @@ func runTests(t *testing.T, walletDriver *lnwallet.WalletDriver,
// Create a btcwallet bitcoind client for both Alice and // Create a btcwallet bitcoind client for both Alice and
// Bob. // Bob.
aliceClient = chainConn.NewBitcoindClient(time.Unix(0, 0)) aliceClient = chainConn.NewBitcoindClient()
bobClient = chainConn.NewBitcoindClient(time.Unix(0, 0)) bobClient = chainConn.NewBitcoindClient()
default: default:
t.Fatalf("unknown chain driver: %v", backEnd) t.Fatalf("unknown chain driver: %v", backEnd)
} }

View file

@ -6,7 +6,6 @@ import (
"fmt" "fmt"
"sync" "sync"
"sync/atomic" "sync/atomic"
"time"
"github.com/btcsuite/btcd/btcjson" "github.com/btcsuite/btcd/btcjson"
"github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/btcsuite/btcd/chaincfg/chainhash"
@ -71,7 +70,7 @@ func NewBitcoindFilteredChainView(
quit: make(chan struct{}), quit: make(chan struct{}),
} }
chainView.chainClient = chainConn.NewBitcoindClient(time.Unix(0, 0)) chainView.chainClient = chainConn.NewBitcoindClient()
chainView.blockQueue = newBlockEventQueue() chainView.blockQueue = newBlockEventQueue()
return chainView return chainView