2020-04-01 17:06:35 +02:00
|
|
|
package clientdb
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"fmt"
|
2020-04-23 11:35:16 -07:00
|
|
|
"strings"
|
2020-04-01 17:06:35 +02:00
|
|
|
"testing"
|
|
|
|
|
|
2022-03-11 14:19:30 -08:00
|
|
|
"github.com/btcsuite/btcd/btcec/v2"
|
|
|
|
|
"github.com/btcsuite/btcd/btcutil"
|
2020-04-30 14:52:38 -07:00
|
|
|
"github.com/btcsuite/btcd/wire"
|
2020-09-09 17:45:32 -07:00
|
|
|
"github.com/lightninglabs/pool/account"
|
|
|
|
|
"github.com/lightninglabs/pool/order"
|
2020-09-07 20:21:31 +02:00
|
|
|
"github.com/lightninglabs/pool/terms"
|
2020-05-05 14:20:49 -07:00
|
|
|
"github.com/lightningnetwork/lnd/keychain"
|
2020-06-24 10:47:23 +02:00
|
|
|
"go.etcd.io/bbolt"
|
2020-04-01 17:06:35 +02:00
|
|
|
)
|
|
|
|
|
|
2020-04-24 16:09:15 -07:00
|
|
|
var (
|
|
|
|
|
testBatchID = order.BatchID{0x01, 0x02, 0x03}
|
2020-04-01 17:06:35 +02:00
|
|
|
|
2020-04-30 14:52:38 -07:00
|
|
|
testBatchTx = &wire.MsgTx{
|
|
|
|
|
Version: 2,
|
|
|
|
|
TxIn: []*wire.TxIn{
|
2020-09-07 20:35:01 +02:00
|
|
|
{
|
|
|
|
|
PreviousOutPoint: wire.OutPoint{
|
|
|
|
|
Index: 1,
|
|
|
|
|
},
|
|
|
|
|
SignatureScript: []byte("aaa"),
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
TxOut: []*wire.TxOut{
|
|
|
|
|
{
|
|
|
|
|
Value: 4444,
|
|
|
|
|
PkScript: []byte("ddd"),
|
|
|
|
|
},
|
2020-04-30 14:52:38 -07:00
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
|
2020-09-07 20:21:31 +02:00
|
|
|
testBatch = &order.Batch{
|
|
|
|
|
ID: testBatchID,
|
|
|
|
|
ExecutionFee: terms.NewLinearFeeSchedule(10, 100),
|
|
|
|
|
BatchTX: testBatchTx,
|
|
|
|
|
}
|
|
|
|
|
|
2020-04-24 16:09:15 -07:00
|
|
|
testCases = []struct {
|
2020-04-01 17:06:35 +02:00
|
|
|
name string
|
|
|
|
|
expectedErr string
|
|
|
|
|
runTest func(db *DB, a *order.Ask, b *order.Bid,
|
|
|
|
|
acct *account.Account) error
|
|
|
|
|
}{
|
|
|
|
|
{
|
|
|
|
|
name: "len mismatch order",
|
|
|
|
|
expectedErr: "order modifier length mismatch",
|
|
|
|
|
runTest: func(db *DB, a *order.Ask, _ *order.Bid,
|
|
|
|
|
_ *account.Account) error {
|
|
|
|
|
|
2020-04-23 11:35:16 -07:00
|
|
|
return db.StorePendingBatch(
|
2020-09-07 20:21:31 +02:00
|
|
|
testBatch,
|
2020-04-30 14:52:38 -07:00
|
|
|
[]order.Nonce{a.Nonce()}, nil, nil, nil,
|
2020-04-01 17:06:35 +02:00
|
|
|
)
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "len mismatch account",
|
|
|
|
|
expectedErr: "account modifier length mismatch",
|
|
|
|
|
runTest: func(db *DB, a *order.Ask, _ *order.Bid,
|
|
|
|
|
acct *account.Account) error {
|
|
|
|
|
|
2020-04-23 11:35:16 -07:00
|
|
|
return db.StorePendingBatch(
|
2020-09-07 20:21:31 +02:00
|
|
|
testBatch, nil, nil,
|
2020-04-23 11:35:16 -07:00
|
|
|
[]*account.Account{acct}, nil,
|
2020-04-01 17:06:35 +02:00
|
|
|
)
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "non-existent order",
|
|
|
|
|
expectedErr: ErrNoOrder.Error(),
|
|
|
|
|
runTest: func(db *DB, a *order.Ask, _ *order.Bid,
|
|
|
|
|
acct *account.Account) error {
|
|
|
|
|
|
|
|
|
|
modifiers := [][]order.Modifier{{
|
|
|
|
|
order.StateModifier(order.StateExecuted),
|
|
|
|
|
}}
|
2020-04-23 11:35:16 -07:00
|
|
|
return db.StorePendingBatch(
|
2020-09-07 20:21:31 +02:00
|
|
|
testBatch,
|
2020-04-30 14:52:38 -07:00
|
|
|
[]order.Nonce{{0, 1, 2}}, modifiers,
|
|
|
|
|
nil, nil,
|
2020-04-01 17:06:35 +02:00
|
|
|
)
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "non-existent account",
|
|
|
|
|
expectedErr: ErrAccountNotFound.Error(),
|
|
|
|
|
runTest: func(db *DB, a *order.Ask, _ *order.Bid,
|
|
|
|
|
acct *account.Account) error {
|
|
|
|
|
|
2020-05-05 14:20:49 -07:00
|
|
|
acct.TraderKey = &keychain.KeyDescriptor{
|
|
|
|
|
KeyLocator: acct.TraderKey.KeyLocator,
|
|
|
|
|
PubKey: testBatchKey,
|
|
|
|
|
}
|
2020-04-01 17:06:35 +02:00
|
|
|
modifiers := [][]account.Modifier{{
|
|
|
|
|
account.StateModifier(account.StateClosed),
|
|
|
|
|
}}
|
2020-04-23 11:35:16 -07:00
|
|
|
return db.StorePendingBatch(
|
2020-09-07 20:21:31 +02:00
|
|
|
testBatch, nil, nil,
|
2020-04-23 11:35:16 -07:00
|
|
|
[]*account.Account{acct}, modifiers,
|
|
|
|
|
)
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "no pending batch",
|
2020-04-30 14:53:27 -07:00
|
|
|
expectedErr: account.ErrNoPendingBatch.Error(),
|
2020-04-23 11:35:16 -07:00
|
|
|
runTest: func(db *DB, a *order.Ask, b *order.Bid,
|
|
|
|
|
acct *account.Account) error {
|
|
|
|
|
|
2020-12-08 11:44:07 +01:00
|
|
|
_, err := db.PendingBatchSnapshot()
|
2020-04-23 11:35:16 -07:00
|
|
|
return err
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "mark batch complete without pending",
|
2020-04-30 14:53:27 -07:00
|
|
|
expectedErr: account.ErrNoPendingBatch.Error(),
|
2020-04-23 11:35:16 -07:00
|
|
|
runTest: func(db *DB, a *order.Ask, b *order.Bid,
|
|
|
|
|
acct *account.Account) error {
|
|
|
|
|
|
2020-04-30 14:51:10 -07:00
|
|
|
return db.MarkBatchComplete()
|
2020-04-01 17:06:35 +02:00
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "happy path",
|
|
|
|
|
expectedErr: "",
|
|
|
|
|
runTest: func(db *DB, a *order.Ask, b *order.Bid,
|
|
|
|
|
acct *account.Account) error {
|
|
|
|
|
|
|
|
|
|
// Store some changes to the orders and account.
|
2020-04-23 18:19:05 -07:00
|
|
|
orders := []order.Order{a, b}
|
|
|
|
|
orderNonces := []order.Nonce{a.Nonce(), b.Nonce()}
|
2020-04-01 17:06:35 +02:00
|
|
|
orderModifiers := [][]order.Modifier{
|
|
|
|
|
{order.UnitsFulfilledModifier(42)},
|
|
|
|
|
{order.UnitsFulfilledModifier(21)},
|
|
|
|
|
}
|
|
|
|
|
accounts := []*account.Account{acct}
|
|
|
|
|
acctModifiers := [][]account.Modifier{{
|
|
|
|
|
account.StateModifier(
|
|
|
|
|
account.StatePendingOpen,
|
|
|
|
|
),
|
|
|
|
|
}}
|
2020-04-23 11:35:16 -07:00
|
|
|
err := db.StorePendingBatch(
|
2020-09-07 20:21:31 +02:00
|
|
|
testBatch, orderNonces,
|
2020-04-30 14:52:38 -07:00
|
|
|
orderModifiers, accounts, acctModifiers,
|
2020-04-01 17:06:35 +02:00
|
|
|
)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
2020-04-30 14:52:38 -07:00
|
|
|
// The pending batch ID and transaction should
|
|
|
|
|
// reflect correctly.
|
2020-12-08 11:44:07 +01:00
|
|
|
dbSnapshot, err := db.PendingBatchSnapshot()
|
2020-04-01 17:06:35 +02:00
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
2020-12-08 11:44:07 +01:00
|
|
|
if dbSnapshot.BatchID != testBatchID {
|
2020-04-23 18:19:05 -07:00
|
|
|
return fmt.Errorf("expected pending "+
|
|
|
|
|
"batch id %x, got %x",
|
2020-12-08 11:44:07 +01:00
|
|
|
testBatchID, dbSnapshot.BatchID)
|
2020-04-01 17:06:35 +02:00
|
|
|
}
|
2020-12-08 11:44:07 +01:00
|
|
|
if dbSnapshot.BatchTX.TxHash() != testBatch.BatchTX.TxHash() {
|
2020-04-30 14:52:38 -07:00
|
|
|
return fmt.Errorf("expected pending "+
|
|
|
|
|
"batch tx %v, got %v",
|
2020-09-07 20:21:31 +02:00
|
|
|
testBatch.BatchTX.TxHash(),
|
2020-12-08 11:44:07 +01:00
|
|
|
dbSnapshot.BatchTX.TxHash())
|
2020-04-30 14:52:38 -07:00
|
|
|
}
|
2020-04-23 18:19:05 -07:00
|
|
|
|
|
|
|
|
// Verify the updates have not been applied to
|
|
|
|
|
// disk yet.
|
|
|
|
|
err = checkUpdate(
|
|
|
|
|
db, a.Nonce(), b.Nonce(),
|
|
|
|
|
a.Details().UnitsUnfulfilled,
|
|
|
|
|
b.Details().UnitsUnfulfilled,
|
|
|
|
|
acct.TraderKey.PubKey, acct.State,
|
|
|
|
|
)
|
2020-04-01 17:06:35 +02:00
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
2020-04-23 18:19:05 -07:00
|
|
|
|
|
|
|
|
// Mark the batch as complete.
|
2020-04-30 14:51:10 -07:00
|
|
|
if err := db.MarkBatchComplete(); err != nil {
|
2020-04-01 17:06:35 +02:00
|
|
|
return err
|
|
|
|
|
}
|
2020-04-23 18:19:05 -07:00
|
|
|
|
|
|
|
|
// Verify the updates have been applied to disk
|
|
|
|
|
// properly.
|
|
|
|
|
for i, a := range accounts {
|
|
|
|
|
for _, modifier := range acctModifiers[i] {
|
|
|
|
|
modifier(a)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
for i, o := range orders {
|
|
|
|
|
for _, modifier := range orderModifiers[i] {
|
|
|
|
|
modifier(o.Details())
|
|
|
|
|
}
|
2020-04-01 17:06:35 +02:00
|
|
|
}
|
2020-04-23 18:19:05 -07:00
|
|
|
return checkUpdate(
|
|
|
|
|
db, a.Nonce(), b.Nonce(),
|
|
|
|
|
a.Details().UnitsUnfulfilled,
|
|
|
|
|
b.Details().UnitsUnfulfilled,
|
|
|
|
|
acct.TraderKey.PubKey, acct.State,
|
|
|
|
|
)
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "overwrite pending batch",
|
|
|
|
|
expectedErr: "",
|
|
|
|
|
runTest: func(db *DB, a *order.Ask, b *order.Bid,
|
|
|
|
|
acct *account.Account) error {
|
2020-04-23 11:35:16 -07:00
|
|
|
|
2020-04-23 18:19:05 -07:00
|
|
|
// First, we'll store a version of the batch
|
|
|
|
|
// that updates all order and accounts.
|
|
|
|
|
orderModifier := order.UnitsFulfilledModifier(42)
|
|
|
|
|
err := db.StorePendingBatch(
|
2020-09-07 20:21:31 +02:00
|
|
|
testBatch,
|
2020-04-23 18:19:05 -07:00
|
|
|
[]order.Nonce{a.Nonce(), b.Nonce()},
|
|
|
|
|
[][]order.Modifier{
|
|
|
|
|
{orderModifier}, {orderModifier},
|
|
|
|
|
},
|
|
|
|
|
[]*account.Account{acct},
|
|
|
|
|
[][]account.Modifier{{account.StateModifier(
|
|
|
|
|
account.StatePendingUpdate,
|
|
|
|
|
)}},
|
|
|
|
|
)
|
2020-04-23 11:35:16 -07:00
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
2020-04-23 18:19:05 -07:00
|
|
|
|
|
|
|
|
// Then, we'll assume the batch was overwritten,
|
|
|
|
|
// and now only the ask order is part of it.
|
|
|
|
|
err = db.StorePendingBatch(
|
2020-09-07 20:21:31 +02:00
|
|
|
testBatch,
|
2020-04-23 18:19:05 -07:00
|
|
|
[]order.Nonce{a.Nonce()},
|
|
|
|
|
[][]order.Modifier{{orderModifier}},
|
|
|
|
|
nil, nil,
|
|
|
|
|
)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
2020-04-23 11:35:16 -07:00
|
|
|
}
|
|
|
|
|
|
2020-04-23 18:19:05 -07:00
|
|
|
// Mark the batch as complete. We should only
|
|
|
|
|
// see the update for our ask order applied, but
|
|
|
|
|
// not the rest.
|
2020-04-30 14:51:10 -07:00
|
|
|
if err := db.MarkBatchComplete(); err != nil {
|
2020-04-23 18:19:05 -07:00
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return checkUpdate(
|
|
|
|
|
db, a.Nonce(), b.Nonce(), 42,
|
|
|
|
|
b.UnitsUnfulfilled,
|
|
|
|
|
acct.TraderKey.PubKey, acct.State,
|
|
|
|
|
)
|
2020-04-01 17:06:35 +02:00
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
}
|
2020-04-24 16:09:15 -07:00
|
|
|
)
|
|
|
|
|
|
2020-04-23 18:19:05 -07:00
|
|
|
// checkUpdate is a helper closure we'll use to check whether the account and
|
|
|
|
|
// order updates of a batch have been applied.
|
|
|
|
|
func checkUpdate(db *DB, askNonce, bidNonce order.Nonce,
|
|
|
|
|
askUnitsUnfulfilled, bidUnitsUnfulfilled order.SupplyUnit,
|
|
|
|
|
accountKey *btcec.PublicKey, accountState account.State) error {
|
|
|
|
|
|
|
|
|
|
o1, err := db.GetOrder(askNonce)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
if o1.Details().UnitsUnfulfilled != askUnitsUnfulfilled {
|
|
|
|
|
return fmt.Errorf("unexpected number of unfulfilled "+
|
|
|
|
|
"units, got %d wanted %d",
|
|
|
|
|
o1.Details().UnitsUnfulfilled, askUnitsUnfulfilled)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
o2, err := db.GetOrder(bidNonce)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
if o2.Details().UnitsUnfulfilled != bidUnitsUnfulfilled {
|
|
|
|
|
return fmt.Errorf("unexpected number of unfulfilled "+
|
|
|
|
|
"units, got %d "+"wanted %d",
|
|
|
|
|
o2.Details().UnitsUnfulfilled, bidUnitsUnfulfilled)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
a2, err := db.Account(accountKey)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
if a2.State != accountState {
|
|
|
|
|
return fmt.Errorf("unexpected state of account, got "+
|
|
|
|
|
"%v wanted %v", a2.State, accountState)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
2020-04-24 16:09:15 -07:00
|
|
|
// TestPersistBatchResult tests that a batch result can be persisted correctly.
|
|
|
|
|
func TestPersistBatchResult(t *testing.T) {
|
|
|
|
|
t.Parallel()
|
2020-04-01 17:06:35 +02:00
|
|
|
|
|
|
|
|
for _, tc := range testCases {
|
|
|
|
|
tc := tc
|
|
|
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
|
|
|
// Create a new store every time to make sure we start
|
|
|
|
|
// with a clean slate.
|
|
|
|
|
store, cleanup := newTestDB(t)
|
|
|
|
|
defer cleanup()
|
|
|
|
|
|
|
|
|
|
// Create a test account and two matching orders that
|
|
|
|
|
// spend from that account. This never happens in real
|
|
|
|
|
// life but is good enough to just test the database.
|
|
|
|
|
acct := &account.Account{
|
|
|
|
|
Value: btcutil.SatoshiPerBitcoin,
|
|
|
|
|
Expiry: 1337,
|
|
|
|
|
TraderKey: testTraderKeyDesc,
|
|
|
|
|
AuctioneerKey: testAuctioneerKey,
|
|
|
|
|
BatchKey: testBatchKey,
|
|
|
|
|
Secret: sharedSecret,
|
|
|
|
|
State: account.StateOpen,
|
|
|
|
|
HeightHint: 1,
|
|
|
|
|
}
|
2020-08-26 16:34:04 -07:00
|
|
|
accountOutput, err := acct.Output()
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
acct.LatestTx = &wire.MsgTx{
|
|
|
|
|
Version: 2,
|
|
|
|
|
TxIn: []*wire.TxIn{
|
|
|
|
|
{
|
|
|
|
|
PreviousOutPoint: wire.OutPoint{
|
|
|
|
|
Index: 1,
|
|
|
|
|
},
|
|
|
|
|
SignatureScript: []byte{0x40},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
TxOut: []*wire.TxOut{accountOutput},
|
|
|
|
|
}
|
2020-04-01 17:06:35 +02:00
|
|
|
ask := &order.Ask{
|
2020-09-28 19:11:12 -07:00
|
|
|
Kit: *dummyOrder(900000, 1337),
|
2020-04-01 17:06:35 +02:00
|
|
|
}
|
|
|
|
|
ask.State = order.StateSubmitted
|
|
|
|
|
bid := &order.Bid{
|
2020-09-28 19:11:12 -07:00
|
|
|
Kit: *dummyOrder(900000, 1337),
|
2020-04-01 17:06:35 +02:00
|
|
|
}
|
|
|
|
|
bid.State = order.StateSubmitted
|
|
|
|
|
|
|
|
|
|
// Prepare the DB state by storing our test account and
|
|
|
|
|
// orders.
|
2020-08-26 16:34:04 -07:00
|
|
|
err = store.AddAccount(acct)
|
2020-04-01 17:06:35 +02:00
|
|
|
if err != nil {
|
|
|
|
|
t.Fatalf("error storing test account: %v", err)
|
|
|
|
|
}
|
|
|
|
|
err = store.SubmitOrder(ask)
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatalf("error storing test ask: %v", err)
|
|
|
|
|
}
|
|
|
|
|
err = store.SubmitOrder(bid)
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatalf("error storing test bid: %v", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Run the test case and verify the result.
|
|
|
|
|
err = tc.runTest(store, ask, bid, acct)
|
2020-04-23 18:19:05 -07:00
|
|
|
switch {
|
|
|
|
|
case err == nil && tc.expectedErr != "":
|
|
|
|
|
case err != nil && tc.expectedErr != "":
|
|
|
|
|
if strings.Contains(err.Error(), tc.expectedErr) {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
case err != nil && tc.expectedErr == "":
|
|
|
|
|
default:
|
|
|
|
|
return
|
2020-04-01 17:06:35 +02:00
|
|
|
}
|
2020-04-23 18:19:05 -07:00
|
|
|
|
|
|
|
|
t.Fatalf("unexpected error '%s', expected '%s'",
|
|
|
|
|
err.Error(), tc.expectedErr)
|
2020-04-01 17:06:35 +02:00
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-04-30 14:53:38 -07:00
|
|
|
|
|
|
|
|
// TestDeletePendingBatch ensures that all references of a pending batch have
|
|
|
|
|
// been removed after an invocation of DeletePendingBatch.
|
|
|
|
|
func TestDeletePendingBatch(t *testing.T) {
|
|
|
|
|
t.Parallel()
|
|
|
|
|
|
|
|
|
|
db, cleanup := newTestDB(t)
|
|
|
|
|
defer cleanup()
|
|
|
|
|
|
|
|
|
|
// Helper closure to assert that the sub-keys and sub-buckets of the
|
|
|
|
|
// root batch bucket exist or not.
|
|
|
|
|
assertPendingBatch := func(exists bool) {
|
|
|
|
|
t.Helper()
|
|
|
|
|
|
|
|
|
|
err := db.View(func(tx *bbolt.Tx) error {
|
|
|
|
|
root := tx.Bucket(batchBucketKey)
|
|
|
|
|
|
|
|
|
|
if (root.Get(pendingBatchIDKey) != nil) != exists {
|
|
|
|
|
return fmt.Errorf("found unexpected key %v",
|
|
|
|
|
string(pendingBatchIDKey))
|
|
|
|
|
}
|
|
|
|
|
if (root.Bucket(pendingBatchAccountsBucketKey) != nil) != exists {
|
|
|
|
|
return fmt.Errorf("found unexpected bucket %v",
|
|
|
|
|
string(pendingBatchAccountsBucketKey))
|
|
|
|
|
}
|
|
|
|
|
if (root.Bucket(pendingBatchOrdersBucketKey) != nil) != exists {
|
|
|
|
|
return fmt.Errorf("found unexpected bucket %v",
|
|
|
|
|
string(pendingBatchOrdersBucketKey))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
})
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Store a pending batch. We should expect to find valid values for all
|
|
|
|
|
// sub-keys and sub-buckets.
|
2020-09-07 20:21:31 +02:00
|
|
|
err := db.StorePendingBatch(testBatch, nil, nil, nil, nil)
|
2020-04-30 14:53:38 -07:00
|
|
|
if err != nil {
|
|
|
|
|
t.Fatalf("unable to store pending batch: %v", err)
|
|
|
|
|
}
|
|
|
|
|
assertPendingBatch(true)
|
|
|
|
|
|
|
|
|
|
// Now, delete the pending batch. We should expect to _not_ find any
|
|
|
|
|
// existing sub-keys or sub-buckets.
|
|
|
|
|
if err := db.DeletePendingBatch(); err != nil {
|
|
|
|
|
t.Fatalf("unable to delete pending batch: %v", err)
|
|
|
|
|
}
|
|
|
|
|
assertPendingBatch(false)
|
|
|
|
|
}
|