chanbackup: encode broadcast height in chan ID for unconfirmed channels
This commit is contained in:
parent
cb2b8b4513
commit
d4f836ecb3
@ -66,6 +66,9 @@ type Single struct {
|
|||||||
// ShortChannelID encodes the exact location in the chain in which the
|
// ShortChannelID encodes the exact location in the chain in which the
|
||||||
// channel was initially confirmed. This includes: the block height,
|
// channel was initially confirmed. This includes: the block height,
|
||||||
// transaction index, and the output within the target transaction.
|
// transaction index, and the output within the target transaction.
|
||||||
|
// Channels that were not confirmed at the time of backup creation will
|
||||||
|
// have the funding TX broadcast height set as their block height in
|
||||||
|
// the ShortChannelID.
|
||||||
ShortChannelID lnwire.ShortChannelID
|
ShortChannelID lnwire.ShortChannelID
|
||||||
|
|
||||||
// RemoteNodePub is the identity public key of the remote node this
|
// RemoteNodePub is the identity public key of the remote node this
|
||||||
@ -126,11 +129,21 @@ func NewSingle(channel *channeldb.OpenChannel,
|
|||||||
// key.
|
// key.
|
||||||
_, shaChainPoint := btcec.PrivKeyFromBytes(btcec.S256(), b.Bytes())
|
_, shaChainPoint := btcec.PrivKeyFromBytes(btcec.S256(), b.Bytes())
|
||||||
|
|
||||||
|
// If a channel is unconfirmed, the block height of the ShortChannelID
|
||||||
|
// is zero. This will lead to problems when trying to restore that
|
||||||
|
// channel as the spend notifier would get a height hint of zero.
|
||||||
|
// To work around that problem, we add the channel broadcast height
|
||||||
|
// to the channel ID so we can use that as height hint on restore.
|
||||||
|
chanID := channel.ShortChanID()
|
||||||
|
if chanID.BlockHeight == 0 {
|
||||||
|
chanID.BlockHeight = channel.FundingBroadcastHeight
|
||||||
|
}
|
||||||
|
|
||||||
single := Single{
|
single := Single{
|
||||||
IsInitiator: channel.IsInitiator,
|
IsInitiator: channel.IsInitiator,
|
||||||
ChainHash: channel.ChainHash,
|
ChainHash: channel.ChainHash,
|
||||||
FundingOutpoint: channel.FundingOutpoint,
|
FundingOutpoint: channel.FundingOutpoint,
|
||||||
ShortChannelID: channel.ShortChannelID,
|
ShortChannelID: chanID,
|
||||||
RemoteNodePub: channel.IdentityPub,
|
RemoteNodePub: channel.IdentityPub,
|
||||||
Addresses: nodeAddrs,
|
Addresses: nodeAddrs,
|
||||||
Capacity: channel.Capacity,
|
Capacity: channel.Capacity,
|
||||||
|
@ -410,4 +410,44 @@ func TestSinglePackStaticChanBackups(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestSingleUnconfirmedChannel tests that unconfirmed channels get serialized
|
||||||
|
// correctly by encoding the funding broadcast height as block height of the
|
||||||
|
// short channel ID.
|
||||||
|
func TestSingleUnconfirmedChannel(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
var fundingBroadcastHeight = uint32(1234)
|
||||||
|
|
||||||
|
// Let's create an open channel shell that contains all the information
|
||||||
|
// we need to create a static channel backup but simulate an
|
||||||
|
// unconfirmed channel by setting the block height to 0.
|
||||||
|
channel, err := genRandomOpenChannelShell()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unable to gen open channel: %v", err)
|
||||||
|
}
|
||||||
|
channel.ShortChannelID.BlockHeight = 0
|
||||||
|
channel.FundingBroadcastHeight = fundingBroadcastHeight
|
||||||
|
|
||||||
|
singleChanBackup := NewSingle(channel, []net.Addr{addr1, addr2})
|
||||||
|
keyRing := &mockKeyRing{}
|
||||||
|
|
||||||
|
// Pack it and then unpack it again to make sure everything is written
|
||||||
|
// correctly, then check that the block height of the unpacked
|
||||||
|
// is the funding broadcast height we set before.
|
||||||
|
var b bytes.Buffer
|
||||||
|
if err := singleChanBackup.PackToWriter(&b, keyRing); err != nil {
|
||||||
|
t.Fatalf("unable to pack single: %v", err)
|
||||||
|
}
|
||||||
|
var unpackedSingle Single
|
||||||
|
err = unpackedSingle.UnpackFromReader(&b, keyRing)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unable to unpack single: %v", err)
|
||||||
|
}
|
||||||
|
if unpackedSingle.ShortChannelID.BlockHeight != fundingBroadcastHeight {
|
||||||
|
t.Fatalf("invalid block height. got %d expected %d.",
|
||||||
|
unpackedSingle.ShortChannelID.BlockHeight,
|
||||||
|
fundingBroadcastHeight)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TODO(roasbsef): fuzz parsing
|
// TODO(roasbsef): fuzz parsing
|
||||||
|
Loading…
Reference in New Issue
Block a user