channeldb: add historical channel bucket lookup

This commit is contained in:
carla 2020-02-21 13:23:30 +02:00
parent 94717a2088
commit 8d632b8022
No known key found for this signature in database
GPG Key ID: 4CA7FE54A6213C91
3 changed files with 106 additions and 0 deletions

View File

@ -1249,3 +1249,50 @@ func getMigrationsToApply(versions []version, version uint32) ([]migration, []ui
return migrations, migrationVersions
}
// fetchHistoricalChanBucket returns a the channel bucket for a given outpoint
// from the historical channel bucket. If the bucket does not exist,
// ErrNoHistoricalBucket is returned.
func fetchHistoricalChanBucket(tx *bbolt.Tx,
outPoint *wire.OutPoint) (*bbolt.Bucket, error) {
// First fetch the top level bucket which stores all data related to
// historically stored channels.
historicalChanBucket := tx.Bucket(historicalChannelBucket)
if historicalChanBucket == nil {
return nil, ErrNoHistoricalBucket
}
// With the bucket for the node and chain fetched, we can now go down
// another level, for the channel itself.
var chanPointBuf bytes.Buffer
if err := writeOutpoint(&chanPointBuf, outPoint); err != nil {
return nil, err
}
chanBucket := historicalChanBucket.Bucket(chanPointBuf.Bytes())
if chanBucket == nil {
return nil, ErrChannelNotFound
}
return chanBucket, nil
}
// FetchHistoricalChannel fetches open channel data from the historical channel
// bucket.
func (d *DB) FetchHistoricalChannel(outPoint *wire.OutPoint) (*OpenChannel, error) {
var channel *OpenChannel
err := d.View(func(tx *bbolt.Tx) error {
chanBucket, err := fetchHistoricalChanBucket(tx, outPoint)
if err != nil {
return err
}
channel, err = fetchOpenChannel(chanBucket, outPoint)
return err
})
if err != nil {
return nil, err
}
return channel, nil
}

View File

@ -693,3 +693,57 @@ func TestFetchChannels(t *testing.T) {
})
}
}
// TestFetchHistoricalChannel tests lookup of historical channels.
func TestFetchHistoricalChannel(t *testing.T) {
cdb, cleanUp, err := makeTestDB()
if err != nil {
t.Fatalf("unable to make test database: %v", err)
}
defer cleanUp()
// Create a an open channel in the database.
channel := createTestChannel(t, cdb, openChannelOption())
// First, try to lookup a channel when the bucket does not
// exist.
_, err = cdb.FetchHistoricalChannel(&channel.FundingOutpoint)
if err != ErrNoHistoricalBucket {
t.Fatalf("expected no bucket, got: %v", err)
}
// Close the channel so that it will be written to the historical
// bucket. The values provided in the channel close summary are the
// minimum required for this call to run without panicking.
if err := channel.CloseChannel(&ChannelCloseSummary{
ChanPoint: channel.FundingOutpoint,
RemotePub: channel.IdentityPub,
SettledBalance: btcutil.Amount(500),
}); err != nil {
t.Fatalf("unexpected error closing channel: %v", err)
}
histChannel, err := cdb.FetchHistoricalChannel(&channel.FundingOutpoint)
if err != nil {
t.Fatalf("unexepected error getting channel: %v", err)
}
// Set the db on our channel to nil so that we can check that all other
// fields on the channel equal those on the historical channel.
channel.Db = nil
if !reflect.DeepEqual(histChannel, channel) {
t.Fatalf("expected: %v, got: %v", channel, histChannel)
}
// Create an outpoint that will not be in the db and look it up.
badOutpoint := &wire.OutPoint{
Hash: channel.FundingOutpoint.Hash,
Index: channel.FundingOutpoint.Index + 1,
}
_, err = cdb.FetchHistoricalChannel(badOutpoint)
if err != ErrChannelNotFound {
t.Fatalf("expected chan not found, got: %v", err)
}
}

View File

@ -10,6 +10,11 @@ var (
// created.
ErrNoChanDBExists = fmt.Errorf("channel db has not yet been created")
// ErrNoHistoricalBucket is returned when the historical channel bucket
// not been created yet.
ErrNoHistoricalBucket = fmt.Errorf("historical channel bucket has " +
"not yet been created")
// ErrDBReversion is returned when detecting an attempt to revert to a
// prior database version.
ErrDBReversion = fmt.Errorf("channel db cannot revert to prior version")