sweep: add list sweeps function

This commit is contained in:
carla 2020-05-05 21:10:11 +02:00
parent 537dac3c62
commit 99a45e968a
No known key found for this signature in database
GPG Key ID: 4CA7FE54A6213C91
4 changed files with 74 additions and 2 deletions

@ -39,6 +39,8 @@ var (
utxnFinalizedKndrTxnKey = []byte("finalized-kndr-txn") utxnFinalizedKndrTxnKey = []byte("finalized-kndr-txn")
byteOrder = binary.BigEndian byteOrder = binary.BigEndian
errNoTxHashesBucket = errors.New("tx hashes bucket does not exist")
) )
// SweeperStore stores published txes. // SweeperStore stores published txes.
@ -53,6 +55,9 @@ type SweeperStore interface {
// GetLastPublishedTx returns the last tx that we called NotifyPublishTx // GetLastPublishedTx returns the last tx that we called NotifyPublishTx
// for. // for.
GetLastPublishedTx() (*wire.MsgTx, error) GetLastPublishedTx() (*wire.MsgTx, error)
// ListSweeps lists all the sweeps we have successfully published.
ListSweeps() ([]chainhash.Hash, error)
} }
type sweeperStore struct { type sweeperStore struct {
@ -173,7 +178,7 @@ func (s *sweeperStore) NotifyPublishTx(sweepTx *wire.MsgTx) error {
txHashesBucket := tx.ReadWriteBucket(txHashesBucketKey) txHashesBucket := tx.ReadWriteBucket(txHashesBucketKey)
if txHashesBucket == nil { if txHashesBucket == nil {
return errors.New("tx hashes bucket does not exist") return errNoTxHashesBucket
} }
var b bytes.Buffer var b bytes.Buffer
@ -230,7 +235,7 @@ func (s *sweeperStore) IsOurTx(hash chainhash.Hash) (bool, error) {
err := kvdb.View(s.db, func(tx kvdb.ReadTx) error { err := kvdb.View(s.db, func(tx kvdb.ReadTx) error {
txHashesBucket := tx.ReadBucket(txHashesBucketKey) txHashesBucket := tx.ReadBucket(txHashesBucketKey)
if txHashesBucket == nil { if txHashesBucket == nil {
return errors.New("tx hashes bucket does not exist") return errNoTxHashesBucket
} }
ours = txHashesBucket.Get(hash[:]) != nil ours = txHashesBucket.Get(hash[:]) != nil
@ -244,5 +249,32 @@ func (s *sweeperStore) IsOurTx(hash chainhash.Hash) (bool, error) {
return ours, nil return ours, nil
} }
// ListSweeps lists all the sweep transactions we have in the sweeper store.
func (s *sweeperStore) ListSweeps() ([]chainhash.Hash, error) {
var sweepTxns []chainhash.Hash
if err := kvdb.View(s.db, func(tx kvdb.ReadTx) error {
txHashesBucket := tx.ReadBucket(txHashesBucketKey)
if txHashesBucket == nil {
return errNoTxHashesBucket
}
return txHashesBucket.ForEach(func(resKey, _ []byte) error {
txid, err := chainhash.NewHash(resKey)
if err != nil {
return err
}
sweepTxns = append(sweepTxns, *txid)
return nil
})
}); err != nil {
return nil, err
}
return sweepTxns, nil
}
// Compile-time constraint to ensure sweeperStore implements SweeperStore. // Compile-time constraint to ensure sweeperStore implements SweeperStore.
var _ SweeperStore = (*sweeperStore)(nil) var _ SweeperStore = (*sweeperStore)(nil)

@ -41,5 +41,15 @@ func (s *MockSweeperStore) GetLastPublishedTx() (*wire.MsgTx, error) {
return s.lastTx, nil return s.lastTx, nil
} }
// ListSweeps lists all the sweeps we have successfully published.
func (s *MockSweeperStore) ListSweeps() ([]chainhash.Hash, error) {
var txns []chainhash.Hash
for tx := range s.ourTxes {
txns = append(txns, tx)
}
return txns, nil
}
// Compile-time constraint to ensure MockSweeperStore implements SweeperStore. // Compile-time constraint to ensure MockSweeperStore implements SweeperStore.
var _ SweeperStore = (*MockSweeperStore)(nil) var _ SweeperStore = (*MockSweeperStore)(nil)

@ -150,4 +150,28 @@ func testStore(t *testing.T, createStore func() (SweeperStore, error)) {
if ours { if ours {
t.Fatal("expected tx to be not ours") t.Fatal("expected tx to be not ours")
} }
txns, err := store.ListSweeps()
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
// Create a map containing the sweeps we expect to be returned by list
// sweeps.
expected := map[chainhash.Hash]bool{
tx1.TxHash(): true,
tx2.TxHash(): true,
}
if len(txns) != len(expected) {
t.Fatalf("expected: %v sweeps, got: %v", len(expected),
len(txns))
}
for _, tx := range txns {
_, ok := expected[tx]
if !ok {
t.Fatalf("unexpected tx: %v", tx)
}
}
} }

@ -9,6 +9,7 @@ import (
"sync/atomic" "sync/atomic"
"time" "time"
"github.com/btcsuite/btcd/chaincfg/chainhash"
"github.com/btcsuite/btcd/wire" "github.com/btcsuite/btcd/wire"
"github.com/btcsuite/btcutil" "github.com/btcsuite/btcutil"
"github.com/davecgh/go-spew/spew" "github.com/davecgh/go-spew/spew"
@ -1262,6 +1263,11 @@ func DefaultNextAttemptDeltaFunc(attempts int) int32 {
return 1 + rand.Int31n(1<<uint(attempts-1)) return 1 + rand.Int31n(1<<uint(attempts-1))
} }
// ListSweeps returns a list of the the sweeps recorded by the sweep store.
func (s *UtxoSweeper) ListSweeps() ([]chainhash.Hash, error) {
return s.cfg.Store.ListSweeps()
}
// init initializes the random generator for random input rescheduling. // init initializes the random generator for random input rescheduling.
func init() { func init() {
rand.Seed(time.Now().Unix()) rand.Seed(time.Now().Unix())