mirror of
https://github.com/lightningnetwork/lnd.git
synced 2026-08-13 12:32:48 +02:00
graph/db: add v2 fields to ChannelEdgePolicy model
Extend ChannelEdgePolicy to support v2 channel updates by adding: - Version field to track gossip protocol version (v1 or v2). - LastBlockHeight for v2's block-height-based timestamps. - SecondPeer flag to indicate which peer announced the policy in v2. - DisableFlags for v2-specific channel disable signaling. - ExtraSignedFields map for v2 extra signed TLV data. Add version-aware methods: - IsNode1() determines if the policy was announced by node_1, handling both v1 (via ChannelFlags direction bit) and v2 (via SecondPeer). - IsDisabled() checks disable status using ChannelFlags for v1 and DisableFlags for v2. - String() provides version-appropriate string representations. The new fields use zero values for v1 compatibility (Version defaults to GossipVersion1, LastBlockHeight to 0, SecondPeer to false). This lays the groundwork for v2 policy support; a subsequent commit will handle reading and writing these fields from/to the database.
This commit is contained in:
parent
0aa93c93e7
commit
3fe40c6540
15 changed files with 105 additions and 6 deletions
|
|
@ -512,6 +512,7 @@ func (d *testDBGraph) addRandChannel(node1, node2 *btcec.PublicKey,
|
|||
return nil, nil, err
|
||||
}
|
||||
edgePolicy := &models.ChannelEdgePolicy{
|
||||
Version: lnwire.GossipVersion1,
|
||||
SigBytes: testSig.Serialize(),
|
||||
ChannelID: chanID.ToUint64(),
|
||||
LastUpdate: time.Now(),
|
||||
|
|
@ -528,6 +529,7 @@ func (d *testDBGraph) addRandChannel(node1, node2 *btcec.PublicKey,
|
|||
return nil, nil, err
|
||||
}
|
||||
edgePolicy = &models.ChannelEdgePolicy{
|
||||
Version: lnwire.GossipVersion1,
|
||||
SigBytes: testSig.Serialize(),
|
||||
ChannelID: chanID.ToUint64(),
|
||||
LastUpdate: time.Now(),
|
||||
|
|
|
|||
|
|
@ -3423,6 +3423,7 @@ func (d *AuthenticatedGossiper) handleChanUpdate(ctx context.Context,
|
|||
// signs a different SCID than the database SCID, but since there will
|
||||
// only be a difference if AuthProof == nil, this is fine.
|
||||
update := &models.ChannelEdgePolicy{
|
||||
Version: upd.GossipVersion(),
|
||||
SigBytes: upd.Signature.ToSignatureBytes(),
|
||||
ChannelID: chanInfo.ChannelID,
|
||||
LastUpdate: timestamp,
|
||||
|
|
|
|||
|
|
@ -953,6 +953,7 @@ func (b *Builder) ApplyChannelUpdate(msg *lnwire.ChannelUpdate1) bool {
|
|||
}
|
||||
|
||||
update := &models.ChannelEdgePolicy{
|
||||
Version: msg.GossipVersion(),
|
||||
SigBytes: msg.Signature.ToSignatureBytes(),
|
||||
ChannelID: msg.ShortChannelID.ToUint64(),
|
||||
LastUpdate: time.Unix(int64(msg.Timestamp), 0),
|
||||
|
|
|
|||
|
|
@ -166,6 +166,7 @@ func TestIgnoreChannelEdgePolicyForUnknownChannel(t *testing.T) {
|
|||
require.NoError(t, err)
|
||||
|
||||
edgePolicy := &models.ChannelEdgePolicy{
|
||||
Version: lnwire.GossipVersion1,
|
||||
SigBytes: testSig.Serialize(),
|
||||
ChannelID: edge.ChannelID,
|
||||
LastUpdate: testTime,
|
||||
|
|
@ -1219,6 +1220,7 @@ func TestIsStaleEdgePolicy(t *testing.T) {
|
|||
|
||||
// We'll also add two edge policies, one for each direction.
|
||||
edgePolicy := &models.ChannelEdgePolicy{
|
||||
Version: lnwire.GossipVersion1,
|
||||
SigBytes: testSig.Serialize(),
|
||||
ChannelID: edge.ChannelID,
|
||||
LastUpdate: updateTimeStamp,
|
||||
|
|
@ -1233,6 +1235,7 @@ func TestIsStaleEdgePolicy(t *testing.T) {
|
|||
}
|
||||
|
||||
edgePolicy = &models.ChannelEdgePolicy{
|
||||
Version: lnwire.GossipVersion1,
|
||||
SigBytes: testSig.Serialize(),
|
||||
ChannelID: edge.ChannelID,
|
||||
LastUpdate: updateTimeStamp,
|
||||
|
|
@ -1557,6 +1560,7 @@ func parseTestGraph(t *testing.T, useCache bool, path string) (
|
|||
}
|
||||
|
||||
edgePolicy := &models.ChannelEdgePolicy{
|
||||
Version: lnwire.GossipVersion1,
|
||||
SigBytes: testSig.Serialize(),
|
||||
MessageFlags: lnwire.ChanUpdateMsgFlags(
|
||||
edge.MessageFlags,
|
||||
|
|
@ -1939,7 +1943,9 @@ func createTestGraphFromChannels(t *testing.T, useCache bool,
|
|||
channelFlags |= lnwire.ChanUpdateDisabled
|
||||
}
|
||||
|
||||
//nolint:ll
|
||||
edgePolicy := &models.ChannelEdgePolicy{
|
||||
Version: lnwire.GossipVersion1,
|
||||
SigBytes: testSig.Serialize(),
|
||||
MessageFlags: msgFlags,
|
||||
ChannelFlags: channelFlags,
|
||||
|
|
@ -1970,7 +1976,9 @@ func createTestGraphFromChannels(t *testing.T, useCache bool,
|
|||
}
|
||||
channelFlags |= lnwire.ChanUpdateDirection
|
||||
|
||||
//nolint:ll
|
||||
edgePolicy := &models.ChannelEdgePolicy{
|
||||
Version: lnwire.GossipVersion1,
|
||||
SigBytes: testSig.Serialize(),
|
||||
MessageFlags: msgFlags,
|
||||
ChannelFlags: channelFlags,
|
||||
|
|
|
|||
|
|
@ -1044,6 +1044,7 @@ func createChannelEdge(node1, node2 *models.Node) (*models.ChannelEdgeInfo,
|
|||
)
|
||||
|
||||
edge1 := &models.ChannelEdgePolicy{
|
||||
Version: lnwire.GossipVersion1,
|
||||
SigBytes: testSig.Serialize(),
|
||||
ChannelID: chanID,
|
||||
LastUpdate: nextUpdateTime(),
|
||||
|
|
@ -1058,6 +1059,7 @@ func createChannelEdge(node1, node2 *models.Node) (*models.ChannelEdgeInfo,
|
|||
ExtraOpaqueData: []byte{1, 0},
|
||||
}
|
||||
edge2 := &models.ChannelEdgePolicy{
|
||||
Version: lnwire.GossipVersion1,
|
||||
SigBytes: testSig.Serialize(),
|
||||
ChannelID: chanID,
|
||||
LastUpdate: nextUpdateTime(),
|
||||
|
|
@ -1442,6 +1444,7 @@ func randEdgePolicy(chanID uint64) *models.ChannelEdgePolicy {
|
|||
|
||||
func copyEdgePolicy(p *models.ChannelEdgePolicy) *models.ChannelEdgePolicy {
|
||||
return &models.ChannelEdgePolicy{
|
||||
Version: p.Version,
|
||||
SigBytes: p.SigBytes,
|
||||
ChannelID: p.ChannelID,
|
||||
LastUpdate: p.LastUpdate,
|
||||
|
|
@ -1459,6 +1462,7 @@ func copyEdgePolicy(p *models.ChannelEdgePolicy) *models.ChannelEdgePolicy {
|
|||
|
||||
func newEdgePolicy(chanID uint64, updateTime int64) *models.ChannelEdgePolicy {
|
||||
return &models.ChannelEdgePolicy{
|
||||
Version: lnwire.GossipVersion1,
|
||||
ChannelID: chanID,
|
||||
LastUpdate: time.Unix(updateTime, 0),
|
||||
MessageFlags: 1,
|
||||
|
|
@ -3454,6 +3458,7 @@ func TestFilterChannelRange(t *testing.T) {
|
|||
updateTime = time.Unix(updateTimeSeed, 0)
|
||||
err = graph.UpdateEdgePolicy(
|
||||
ctx, &models.ChannelEdgePolicy{
|
||||
Version: lnwire.GossipVersion1,
|
||||
ToNode: node.PubKeyBytes,
|
||||
ChannelFlags: chanFlags,
|
||||
ChannelID: chanID,
|
||||
|
|
@ -4747,6 +4752,7 @@ func TestLightningNodeSigVerification(t *testing.T) {
|
|||
func TestComputeFee(t *testing.T) {
|
||||
var (
|
||||
policy = models.ChannelEdgePolicy{
|
||||
Version: lnwire.GossipVersion1,
|
||||
FeeBaseMSat: 10000,
|
||||
FeeProportionalMillionths: 30000,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,6 +14,10 @@ import (
|
|||
// information concerning fees, and minimum time-lock information which is
|
||||
// utilized during path finding.
|
||||
type ChannelEdgePolicy struct {
|
||||
// Version is the gossip version of the channel update that produced
|
||||
// this policy.
|
||||
Version lnwire.GossipVersion
|
||||
|
||||
// SigBytes is the raw bytes of the signature of the channel edge
|
||||
// policy. We'll only parse these if the caller needs to access the
|
||||
// signature for validation purposes.
|
||||
|
|
@ -28,6 +32,14 @@ type ChannelEdgePolicy struct {
|
|||
// was received.
|
||||
LastUpdate time.Time
|
||||
|
||||
// LastBlockHeight is the block height that timestamps the last update
|
||||
// for v2 channel updates.
|
||||
LastBlockHeight uint32
|
||||
|
||||
// SecondPeer indicates whether this policy was announced by the second
|
||||
// peer in the channel for v2 channel updates.
|
||||
SecondPeer bool
|
||||
|
||||
// MessageFlags is a bitfield which indicates the presence of optional
|
||||
// fields (like max_htlc) in the policy.
|
||||
MessageFlags lnwire.ChanUpdateMsgFlags
|
||||
|
|
@ -36,6 +48,10 @@ type ChannelEdgePolicy struct {
|
|||
// channel as well as the directed edge this update applies to.
|
||||
ChannelFlags lnwire.ChanUpdateChanFlags
|
||||
|
||||
// DisableFlags is a v2-specific bitfield which signals whether the
|
||||
// channel is disabled for incoming or outgoing traffic.
|
||||
DisableFlags lnwire.ChanUpdateDisableFlags
|
||||
|
||||
// TimeLockDelta is the number of blocks this node will subtract from
|
||||
// the expiry of an incoming HTLC. This value expresses the time buffer
|
||||
// the node would like to HTLC exchanges.
|
||||
|
|
@ -77,11 +93,31 @@ type ChannelEdgePolicy struct {
|
|||
// and ensure we're able to make upgrades to the network in a forwards
|
||||
// compatible manner.
|
||||
ExtraOpaqueData lnwire.ExtraOpaqueData
|
||||
|
||||
// ExtraSignedFields are the extra signed fields found in v2 channel
|
||||
// updates.
|
||||
ExtraSignedFields map[uint64][]byte
|
||||
}
|
||||
|
||||
// IsNode1 returns true if this policy was announced by the channel's node_1.
|
||||
func (c *ChannelEdgePolicy) IsNode1() bool {
|
||||
if c.Version == lnwire.GossipVersion1 {
|
||||
return c.ChannelFlags&lnwire.ChanUpdateDirection == 0
|
||||
}
|
||||
|
||||
return !c.SecondPeer
|
||||
}
|
||||
|
||||
// IsDisabled determines whether the edge has the disabled bit set.
|
||||
//
|
||||
// NOTE: for v2 channel updates, we return true here only if both the incoming
|
||||
// and outgoing disabled bits are set.
|
||||
func (c *ChannelEdgePolicy) IsDisabled() bool {
|
||||
return c.ChannelFlags.IsDisabled()
|
||||
if c.Version == lnwire.GossipVersion1 {
|
||||
return c.ChannelFlags.IsDisabled()
|
||||
}
|
||||
|
||||
return !c.DisableFlags.IsEnabled()
|
||||
}
|
||||
|
||||
// ComputeFee computes the fee to forward an HTLC of `amt` milli-satoshis over
|
||||
|
|
@ -95,7 +131,13 @@ func (c *ChannelEdgePolicy) ComputeFee(
|
|||
|
||||
// String returns a human-readable version of the channel edge policy.
|
||||
func (c *ChannelEdgePolicy) String() string {
|
||||
return fmt.Sprintf("ChannelID=%v, MessageFlags=%v, ChannelFlags=%v, "+
|
||||
"LastUpdate=%v", c.ChannelID, c.MessageFlags, c.ChannelFlags,
|
||||
c.LastUpdate)
|
||||
if c.Version == lnwire.GossipVersion1 {
|
||||
return fmt.Sprintf("ChannelID=%v, MessageFlags=%v, "+
|
||||
"ChannelFlags=%v, LastUpdate=%v", c.ChannelID,
|
||||
c.MessageFlags, c.ChannelFlags, c.LastUpdate)
|
||||
}
|
||||
|
||||
return fmt.Sprintf("ChannelID=%v, Node1=%v, DisableFlags=%v, "+
|
||||
"BlockHeight=%v", c.ChannelID, !c.SecondPeer,
|
||||
c.DisableFlags, c.LastBlockHeight)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -113,6 +113,7 @@ func randEdgePolicy(chanID *lnwire.ShortChannelID,
|
|||
}
|
||||
|
||||
return &models.ChannelEdgePolicy{
|
||||
Version: lnwire.GossipVersion1,
|
||||
SigBytes: testSig.Serialize(),
|
||||
ChannelID: chanID.ToUint64(),
|
||||
LastUpdate: time.Unix(int64(prand.Int31()), 0),
|
||||
|
|
|
|||
|
|
@ -304,6 +304,7 @@ func (s *Server) ImportGraph(ctx context.Context,
|
|||
|
||||
makePolicy := func(rpcPolicy *lnrpc.RoutingPolicy) *models.ChannelEdgePolicy { //nolint:ll
|
||||
policy := &models.ChannelEdgePolicy{
|
||||
Version: lnwire.GossipVersion1,
|
||||
ChannelID: rpcEdge.ChannelId,
|
||||
LastUpdate: time.Unix(
|
||||
int64(rpcPolicy.LastUpdate), 0,
|
||||
|
|
|
|||
|
|
@ -317,7 +317,9 @@ var shouldIncludeChannelTestCases = []struct {
|
|||
|
||||
return edge
|
||||
}(),
|
||||
//nolint:ll
|
||||
&models.ChannelEdgePolicy{
|
||||
Version: lnwire.GossipVersion1,
|
||||
FeeBaseMSat: 1000,
|
||||
FeeProportionalMillionths: 20,
|
||||
TimeLockDelta: 13,
|
||||
|
|
@ -364,7 +366,9 @@ var shouldIncludeChannelTestCases = []struct {
|
|||
).Once().Return(
|
||||
&models.ChannelEdgeInfo{},
|
||||
&models.ChannelEdgePolicy{},
|
||||
//nolint:ll
|
||||
&models.ChannelEdgePolicy{
|
||||
Version: lnwire.GossipVersion1,
|
||||
FeeBaseMSat: 1000,
|
||||
FeeProportionalMillionths: 20,
|
||||
TimeLockDelta: 13,
|
||||
|
|
@ -409,7 +413,9 @@ var shouldIncludeChannelTestCases = []struct {
|
|||
).Once().Return(
|
||||
&models.ChannelEdgeInfo{},
|
||||
&models.ChannelEdgePolicy{},
|
||||
//nolint:ll
|
||||
&models.ChannelEdgePolicy{
|
||||
Version: lnwire.GossipVersion1,
|
||||
FeeBaseMSat: 1000,
|
||||
FeeProportionalMillionths: 20,
|
||||
TimeLockDelta: 13,
|
||||
|
|
|
|||
|
|
@ -380,9 +380,23 @@ func (c ChanUpdateDisableFlags) IsEnabled() bool {
|
|||
return c == 0
|
||||
}
|
||||
|
||||
// String returns the bitfield flags as a string.
|
||||
// String returns a human-readable representation of the disable flags.
|
||||
func (c ChanUpdateDisableFlags) String() string {
|
||||
return fmt.Sprintf("%08b", c)
|
||||
if c.IsEnabled() {
|
||||
return "Enabled"
|
||||
}
|
||||
|
||||
incoming := c.IncomingDisabled()
|
||||
outgoing := c.OutgoingDisabled()
|
||||
|
||||
switch {
|
||||
case incoming && outgoing:
|
||||
return "Disabled(incoming&outgoing)"
|
||||
case incoming:
|
||||
return "Disabled(incoming)"
|
||||
default:
|
||||
return "Disabled(outgoing)"
|
||||
}
|
||||
}
|
||||
|
||||
// Record returns the tlv record for the disable flags.
|
||||
|
|
|
|||
|
|
@ -116,12 +116,14 @@ func createEdgePolicies(t *testing.T, channel *channeldb.OpenChannel,
|
|||
|
||||
return edgeInfo,
|
||||
&models.ChannelEdgePolicy{
|
||||
Version: lnwire.GossipVersion1,
|
||||
ChannelID: channel.ShortChanID().ToUint64(),
|
||||
ChannelFlags: dir1,
|
||||
LastUpdate: time.Now(),
|
||||
SigBytes: testSigBytes,
|
||||
},
|
||||
&models.ChannelEdgePolicy{
|
||||
Version: lnwire.GossipVersion1,
|
||||
ChannelID: channel.ShortChanID().ToUint64(),
|
||||
ChannelFlags: dir2,
|
||||
LastUpdate: time.Now(),
|
||||
|
|
@ -222,6 +224,7 @@ func (g *mockGraph) ApplyChannelUpdate(update *lnwire.ChannelUpdate1,
|
|||
timestamp := time.Unix(int64(update.Timestamp), 0)
|
||||
|
||||
policy := &models.ChannelEdgePolicy{
|
||||
Version: lnwire.GossipVersion1,
|
||||
ChannelID: update.ShortChannelID.ToUint64(),
|
||||
ChannelFlags: update.ChannelFlags,
|
||||
LastUpdate: timestamp,
|
||||
|
|
|
|||
|
|
@ -364,6 +364,7 @@ func (r *Manager) createEdge(channel *channeldb.OpenChannel,
|
|||
// be updated with the new values in the call to processChan below.
|
||||
timeLockDelta := uint16(r.DefaultRoutingPolicy.TimeLockDelta)
|
||||
edge := &models.ChannelEdgePolicy{
|
||||
Version: lnwire.GossipVersion1,
|
||||
ChannelID: shortChanID.ToUint64(),
|
||||
LastUpdate: timestamp,
|
||||
TimeLockDelta: timeLockDelta,
|
||||
|
|
|
|||
|
|
@ -64,6 +64,7 @@ func TestManager(t *testing.T) {
|
|||
}
|
||||
|
||||
currentPolicy := models.ChannelEdgePolicy{
|
||||
Version: lnwire.GossipVersion1,
|
||||
MinHTLC: minHTLC,
|
||||
MessageFlags: lnwire.ChanUpdateRequiredMaxHtlc,
|
||||
}
|
||||
|
|
@ -451,6 +452,7 @@ func TestCreateEdgeLower(t *testing.T) {
|
|||
require.NoError(t, err)
|
||||
|
||||
expectedEdge := &models.ChannelEdgePolicy{
|
||||
Version: lnwire.GossipVersion1,
|
||||
ChannelID: 8,
|
||||
LastUpdate: timestamp,
|
||||
TimeLockDelta: 7,
|
||||
|
|
@ -542,6 +544,7 @@ func TestCreateEdgeHigher(t *testing.T) {
|
|||
require.NoError(t, err)
|
||||
|
||||
expectedEdge := &models.ChannelEdgePolicy{
|
||||
Version: lnwire.GossipVersion1,
|
||||
ChannelID: 8,
|
||||
LastUpdate: timestamp,
|
||||
TimeLockDelta: 7,
|
||||
|
|
|
|||
|
|
@ -389,6 +389,7 @@ func parseTestGraph(t *testing.T, useCache bool, path string) (
|
|||
}
|
||||
|
||||
edgePolicy := &models.ChannelEdgePolicy{
|
||||
Version: lnwire.GossipVersion1,
|
||||
SigBytes: testSig.Serialize(),
|
||||
MessageFlags: lnwire.ChanUpdateMsgFlags(edge.MessageFlags),
|
||||
ChannelFlags: channelFlags,
|
||||
|
|
@ -740,7 +741,9 @@ func createTestGraphFromChannels(t *testing.T, useCache bool,
|
|||
channelFlags |= lnwire.ChanUpdateDisabled
|
||||
}
|
||||
|
||||
//nolint:ll
|
||||
edgePolicy := &models.ChannelEdgePolicy{
|
||||
Version: lnwire.GossipVersion1,
|
||||
SigBytes: testSig.Serialize(),
|
||||
MessageFlags: msgFlags,
|
||||
ChannelFlags: channelFlags,
|
||||
|
|
@ -772,7 +775,9 @@ func createTestGraphFromChannels(t *testing.T, useCache bool,
|
|||
}
|
||||
channelFlags |= lnwire.ChanUpdateDirection
|
||||
|
||||
//nolint:ll
|
||||
edgePolicy := &models.ChannelEdgePolicy{
|
||||
Version: lnwire.GossipVersion1,
|
||||
SigBytes: testSig.Serialize(),
|
||||
MessageFlags: msgFlags,
|
||||
ChannelFlags: channelFlags,
|
||||
|
|
|
|||
|
|
@ -2751,6 +2751,7 @@ func TestAddEdgeUnknownVertexes(t *testing.T) {
|
|||
// We must add the edge policy to be able to use the edge for route
|
||||
// finding.
|
||||
edgePolicy := &models.ChannelEdgePolicy{
|
||||
Version: lnwire.GossipVersion1,
|
||||
SigBytes: testSig.Serialize(),
|
||||
ChannelID: edge.ChannelID,
|
||||
LastUpdate: testTime,
|
||||
|
|
@ -2766,6 +2767,7 @@ func TestAddEdgeUnknownVertexes(t *testing.T) {
|
|||
|
||||
// Create edge in the other direction as well.
|
||||
edgePolicy = &models.ChannelEdgePolicy{
|
||||
Version: lnwire.GossipVersion1,
|
||||
SigBytes: testSig.Serialize(),
|
||||
ChannelID: edge.ChannelID,
|
||||
LastUpdate: testTime,
|
||||
|
|
@ -2832,6 +2834,7 @@ func TestAddEdgeUnknownVertexes(t *testing.T) {
|
|||
require.NoError(t, ctx.graph.AddChannelEdge(ctxb, edge))
|
||||
|
||||
edgePolicy = &models.ChannelEdgePolicy{
|
||||
Version: lnwire.GossipVersion1,
|
||||
SigBytes: testSig.Serialize(),
|
||||
ChannelID: edge.ChannelID,
|
||||
LastUpdate: testTime,
|
||||
|
|
@ -2846,6 +2849,7 @@ func TestAddEdgeUnknownVertexes(t *testing.T) {
|
|||
require.NoError(t, ctx.graph.UpdateEdgePolicy(ctxb, edgePolicy))
|
||||
|
||||
edgePolicy = &models.ChannelEdgePolicy{
|
||||
Version: lnwire.GossipVersion1,
|
||||
SigBytes: testSig.Serialize(),
|
||||
ChannelID: edge.ChannelID,
|
||||
LastUpdate: testTime,
|
||||
|
|
@ -2965,6 +2969,7 @@ func (m *mockGraphBuilder) ApplyChannelUpdate(msg *lnwire.ChannelUpdate1) bool {
|
|||
}
|
||||
|
||||
err := m.updateEdge(&models.ChannelEdgePolicy{
|
||||
Version: msg.GossipVersion(),
|
||||
SigBytes: msg.Signature.ToSignatureBytes(),
|
||||
ChannelID: msg.ShortChannelID.ToUint64(),
|
||||
LastUpdate: time.Unix(int64(msg.Timestamp), 0),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue