graph/db: validate edge policy TLV data before persisting

In this commit, we start validating the extra opaque data of a channel
edge policy before persisting it. We just check that the data is valid
TLV.

NOTE: we recently [started
validating](https://github.com/lightningnetwork/lnd/commit/1410a0949d555e14de11faf81a17fe64917505e3)
this at the lnwire level. So really, no new update will reach the DB
layer without this already being checked. But we check it again here so
that the DB API behaves correctly as its own unit.
This commit is contained in:
Elle Mouton committed 2025-06-09 08:26:11 +02:00
1 parent c6d6d4c0b6
commit 239acb4063
3 files changed
+22 -6

No files matched your search

+4
View File
@@ -12,6 +12,10 @@ var (
ErrEdgePolicyOptionalFieldNotFound = fmt.Errorf("optional field not " +
"present")
// ErrParsingExtraTLVBytes is returned when we attempt to parse
// extra opaque bytes as a TLV stream, but the parsing fails.
ErrParsingExtraTLVBytes = fmt.Errorf("error parsing extra TLV bytes")
// ErrGraphNotFound is returned when at least one of the components of
// graph doesn't exist.
ErrGraphNotFound = fmt.Errorf("graph bucket not initialized")
+12 -6
View File
@@ -4195,19 +4195,25 @@ func TestGraphCacheForEachNodeChannel(t *testing.T) {
directedChan := getSingleChannel()
require.NotNil(t, directedChan)
require.Equal(t, directedChan.InboundFee, lnwire.Fee{
expectedInbound := lnwire.Fee{
BaseFee: 10,
FeeRate: 20,
})
}
require.Equal(t, expectedInbound, directedChan.InboundFee)
// Set an invalid inbound fee and check that the edge is no longer
// returned.
// Set an invalid inbound fee and check that persistence fails.
edge1.ExtraOpaqueData = []byte{
253, 217, 3, 8, 0,
}
require.NoError(t, graph.UpdateEdgePolicy(edge1))
require.ErrorIs(
t, graph.UpdateEdgePolicy(edge1), ErrParsingExtraTLVBytes,
)
require.Nil(t, getSingleChannel())
// Since persistence of the last update failed, we should still bet
// the previous result when we query the channel again.
directedChan = getSingleChannel()
require.NotNil(t, directedChan)
require.Equal(t, expectedInbound, directedChan.InboundFee)
}
// TestGraphLoading asserts that the cache is properly reconstructed after a
+6
View File
@@ -4546,6 +4546,12 @@ func serializeChanEdgePolicy(w io.Writer, edge *models.ChannelEdgePolicy,
}
}
// Validate that the ExtraOpaqueData is in fact a valid TLV stream.
err = edge.ExtraOpaqueData.ValidateTLV()
if err != nil {
return fmt.Errorf("%w: %w", ErrParsingExtraTLVBytes, err)
}
if len(edge.ExtraOpaqueData) > MaxAllowedExtraOpaqueBytes {
return ErrTooManyExtraOpaqueBytes(len(edge.ExtraOpaqueData))
}