diff --git a/graph/db/errors.go b/graph/db/errors.go index afdbdb457..8201980aa 100644 --- a/graph/db/errors.go +++ b/graph/db/errors.go @@ -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") diff --git a/graph/db/graph_test.go b/graph/db/graph_test.go index c8a5c54b2..efe1b4642 100644 --- a/graph/db/graph_test.go +++ b/graph/db/graph_test.go @@ -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 diff --git a/graph/db/kv_store.go b/graph/db/kv_store.go index b08c86022..f68732e81 100644 --- a/graph/db/kv_store.go +++ b/graph/db/kv_store.go @@ -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)) }