channeldb/graph: add max HTLC to ChannelEdgePolicy

Adding this field will allow us to persist an edge's
max HTLC to disk, thus preserving it between restarts.

Co-authored-by: Johan T. Halseth <johanth@gmail.com>
This commit is contained in:
Valentine Wallace 2019-01-12 18:59:44 +01:00 committed by Johan T. Halseth
parent b9c5248915
commit 69d4bf051f
No known key found for this signature in database
GPG Key ID: 15BAADA29DA20D26
2 changed files with 47 additions and 2 deletions

@ -97,6 +97,12 @@ var (
// ErrNoForwardingEvents is returned in the case that a query fails due
// to the log not having any recorded events.
ErrNoForwardingEvents = fmt.Errorf("no recorded forwarding events")
// ErrEdgePolicyOptionalFieldNotFound is an error returned if a channel
// policy field is not found in the db even though its message flags
// indicate it should be.
ErrEdgePolicyOptionalFieldNotFound = fmt.Errorf("optional field not " +
"present")
)
// ErrTooManyExtraOpaqueBytes creates an error which should be returned if the

@ -2439,6 +2439,10 @@ type ChannelEdgePolicy struct {
// in millisatoshi.
MinHTLC lnwire.MilliSatoshi
// MaxHTLC is the largest value HTLC this node will accept, expressed
// in millisatoshi.
MaxHTLC lnwire.MilliSatoshi
// FeeBaseMSat is the base HTLC fee that will be charged for forwarding
// ANY HTLC, expressed in mSAT's.
FeeBaseMSat lnwire.MilliSatoshi
@ -3348,11 +3352,26 @@ func serializeChanEdgePolicy(w io.Writer, edge *ChannelEdgePolicy,
return err
}
// If the max_htlc field is present, we write it. To be compatible with
// older versions that wasn't aware of this field, we write it as part
// of the opaque data.
// TODO(halseth): clean up when moving to TLV.
var opaqueBuf bytes.Buffer
if edge.MessageFlags&lnwire.ChanUpdateOptionMaxHtlc != 0 {
err := binary.Write(&opaqueBuf, byteOrder, uint64(edge.MaxHTLC))
if err != nil {
return err
}
}
if len(edge.ExtraOpaqueData) > MaxAllowedExtraOpaqueBytes {
return ErrTooManyExtraOpaqueBytes(len(edge.ExtraOpaqueData))
}
if _, err := opaqueBuf.Write(edge.ExtraOpaqueData); err != nil {
return err
}
if err := wire.WriteVarBytes(w, 0, edge.ExtraOpaqueData); err != nil {
if err := wire.WriteVarBytes(w, 0, opaqueBuf.Bytes()); err != nil {
return err
}
return nil
@ -3416,6 +3435,7 @@ func deserializeChanEdgePolicy(r io.Reader,
return nil, fmt.Errorf("unable to fetch node: %x, %v",
pub[:], err)
}
edge.Node = &node
// We'll try and see if there are any opaque bytes left, if not, then
// we'll ignore the EOF error and return the edge as is.
@ -3429,6 +3449,25 @@ func deserializeChanEdgePolicy(r io.Reader,
return nil, err
}
edge.Node = &node
// See if optional fields are present.
if edge.MessageFlags&lnwire.ChanUpdateOptionMaxHtlc != 0 {
// The max_htlc field should be at the beginning of the opaque
// bytes.
opq := edge.ExtraOpaqueData
// If the max_htlc field is not present, it might be old data
// stored before this field was validated. We'll return the
// edge along with an error.
if len(opq) < 8 {
return edge, ErrEdgePolicyOptionalFieldNotFound
}
maxHtlc := byteOrder.Uint64(opq[:8])
edge.MaxHTLC = lnwire.MilliSatoshi(maxHtlc)
// Exclude the parsed field from the rest of the opaque data.
edge.ExtraOpaqueData = opq[8:]
}
return edge, nil
}