You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
218 lines
5.0 KiB
218 lines
5.0 KiB
package channeldb |
|
|
|
import ( |
|
"bytes" |
|
"testing" |
|
|
|
"github.com/btcsuite/btcd/chaincfg/chainhash" |
|
"github.com/btcsuite/btcd/wire" |
|
"github.com/lightningnetwork/lnd/kvdb" |
|
"github.com/stretchr/testify/require" |
|
) |
|
|
|
var ( |
|
testChainHash = [chainhash.HashSize]byte{ |
|
0x51, 0xb6, 0x37, 0xd8, 0xfc, 0xd2, 0xc6, 0xda, |
|
0x48, 0x59, 0xe6, 0x96, 0x31, 0x13, 0xa1, 0x17, |
|
0x2d, 0xe7, 0x93, 0xe4, |
|
} |
|
|
|
testChanPoint1 = wire.OutPoint{ |
|
Hash: chainhash.Hash{ |
|
0x51, 0xb6, 0x37, 0xd8, 0xfc, 0xd2, 0xc6, 0xda, |
|
0x48, 0x59, 0xe6, 0x96, 0x31, 0x13, 0xa1, 0x17, |
|
0x2d, 0xe7, 0x93, 0xe4, |
|
}, |
|
Index: 1, |
|
} |
|
) |
|
|
|
// TestPersistReport tests the writing and retrieval of a report on disk with |
|
// and without a spend txid. |
|
func TestPersistReport(t *testing.T) { |
|
tests := []struct { |
|
name string |
|
spendTxID *chainhash.Hash |
|
}{ |
|
{ |
|
name: "Non-nil spend txid", |
|
spendTxID: &testChanPoint1.Hash, |
|
}, |
|
{ |
|
name: "Nil spend txid", |
|
spendTxID: nil, |
|
}, |
|
} |
|
|
|
for _, test := range tests { |
|
test := test |
|
|
|
t.Run(test.name, func(t *testing.T) { |
|
db, cleanup, err := MakeTestDB() |
|
require.NoError(t, err) |
|
defer cleanup() |
|
|
|
channelOutpoint := testChanPoint1 |
|
|
|
testOutpoint := testChanPoint1 |
|
testOutpoint.Index++ |
|
|
|
report := &ResolverReport{ |
|
OutPoint: testOutpoint, |
|
Amount: 2, |
|
ResolverType: 1, |
|
ResolverOutcome: 2, |
|
SpendTxID: test.spendTxID, |
|
} |
|
|
|
// Write report to disk, and ensure it is identical when |
|
// it is read. |
|
err = db.PutResolverReport( |
|
nil, testChainHash, &channelOutpoint, report, |
|
) |
|
require.NoError(t, err) |
|
|
|
reports, err := db.FetchChannelReports( |
|
testChainHash, &channelOutpoint, |
|
) |
|
require.NoError(t, err) |
|
require.Equal(t, report, reports[0]) |
|
}) |
|
} |
|
} |
|
|
|
// TestFetchChannelReadBucket tests retrieval of the reports bucket for a |
|
// channel, testing that the appropriate error is returned based on the state |
|
// of the existing bucket. |
|
func TestFetchChannelReadBucket(t *testing.T) { |
|
db, cleanup, err := MakeTestDB() |
|
require.NoError(t, err) |
|
defer cleanup() |
|
|
|
channelOutpoint := testChanPoint1 |
|
|
|
testOutpoint := testChanPoint1 |
|
testOutpoint.Index++ |
|
|
|
// If we attempt to get reports when we do not have any present, we |
|
// expect to fail because our chain hash bucket is not present. |
|
_, err = db.FetchChannelReports( |
|
testChainHash, &channelOutpoint, |
|
) |
|
require.Equal(t, ErrNoChainHashBucket, err) |
|
|
|
// Finally we write a report to disk and check that we can fetch it. |
|
report := &ResolverReport{ |
|
OutPoint: testOutpoint, |
|
Amount: 2, |
|
ResolverOutcome: 1, |
|
ResolverType: 2, |
|
SpendTxID: nil, |
|
} |
|
|
|
err = db.PutResolverReport( |
|
nil, testChainHash, &channelOutpoint, report, |
|
) |
|
require.NoError(t, err) |
|
|
|
// Now that the channel bucket exists, we expect the channel to be |
|
// successfully fetched, with no reports. |
|
reports, err := db.FetchChannelReports(testChainHash, &testChanPoint1) |
|
require.NoError(t, err) |
|
require.Equal(t, report, reports[0]) |
|
} |
|
|
|
// TestFetchChannelWriteBucket tests the creation of missing buckets when |
|
// retrieving the reports bucket. |
|
func TestFetchChannelWriteBucket(t *testing.T) { |
|
createReportsBucket := func(tx kvdb.RwTx) (kvdb.RwBucket, error) { |
|
return tx.CreateTopLevelBucket(closedChannelBucket) |
|
} |
|
|
|
createChainHashBucket := func(reports kvdb.RwBucket) (kvdb.RwBucket, |
|
error) { |
|
|
|
return reports.CreateBucketIfNotExists(testChainHash[:]) |
|
} |
|
|
|
createChannelBucket := func(chainHash kvdb.RwBucket) (kvdb.RwBucket, |
|
error) { |
|
|
|
var chanPointBuf bytes.Buffer |
|
err := writeOutpoint(&chanPointBuf, &testChanPoint1) |
|
require.NoError(t, err) |
|
|
|
return chainHash.CreateBucketIfNotExists(chanPointBuf.Bytes()) |
|
} |
|
|
|
tests := []struct { |
|
name string |
|
setup func(tx kvdb.RwTx) error |
|
}{ |
|
{ |
|
name: "no existing buckets", |
|
setup: func(tx kvdb.RwTx) error { |
|
return nil |
|
}, |
|
}, |
|
{ |
|
name: "reports bucket exists", |
|
setup: func(tx kvdb.RwTx) error { |
|
_, err := createReportsBucket(tx) |
|
return err |
|
}, |
|
}, |
|
{ |
|
name: "chainhash bucket exists", |
|
setup: func(tx kvdb.RwTx) error { |
|
reports, err := createReportsBucket(tx) |
|
if err != nil { |
|
return err |
|
} |
|
|
|
_, err = createChainHashBucket(reports) |
|
return err |
|
}, |
|
}, |
|
{ |
|
name: "channel bucket exists", |
|
setup: func(tx kvdb.RwTx) error { |
|
reports, err := createReportsBucket(tx) |
|
if err != nil { |
|
return err |
|
} |
|
|
|
chainHash, err := createChainHashBucket(reports) |
|
if err != nil { |
|
return err |
|
} |
|
|
|
_, err = createChannelBucket(chainHash) |
|
return err |
|
}, |
|
}, |
|
} |
|
|
|
for _, test := range tests { |
|
test := test |
|
|
|
t.Run(test.name, func(t *testing.T) { |
|
db, cleanup, err := MakeTestDB() |
|
require.NoError(t, err) |
|
defer cleanup() |
|
|
|
// Update our db to the starting state we expect. |
|
err = kvdb.Update(db, test.setup, func() {}) |
|
require.NoError(t, err) |
|
|
|
// Try to get our report bucket. |
|
err = kvdb.Update(db, func(tx kvdb.RwTx) error { |
|
_, err := fetchReportWriteBucket( |
|
tx, testChainHash, &testChanPoint1, |
|
) |
|
return err |
|
}, func() {}) |
|
require.NoError(t, err) |
|
}) |
|
} |
|
}
|
|
|