Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TLV encoding: add forward-compatibility #1037

Merged
merged 11 commits into from
Aug 16, 2024
Merged
Prev Previous commit
Next Next commit
commitment: update parsing to return error if unknown even type encou…
…ntered
  • Loading branch information
guggero committed Aug 16, 2024
commit 53904cc00b3b38209f6e1ea43444cbd3c31dd5a4
43 changes: 19 additions & 24 deletions commitment/encoding.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"bytes"
"io"

"github.com/lightninglabs/taproot-assets/asset"
"github.com/lightninglabs/taproot-assets/mssmt"
"github.com/lightningnetwork/lnd/tlv"
)
Expand Down Expand Up @@ -31,12 +32,7 @@ func TapCommitmentVersionDecoder(r io.Reader, val any, buf *[8]byte,

func AssetProofEncoder(w io.Writer, val any, buf *[8]byte) error {
if t, ok := val.(**AssetProof); ok {
records := []tlv.Record{
AssetProofVersionRecord(&(*t).Version),
AssetProofAssetIDRecord(&(*t).TapKey),
AssetProofRecord(&(*t).Proof),
}
stream, err := tlv.NewStream(records...)
stream, err := tlv.NewStream((*t).Records()...)
if err != nil {
return err
}
Expand All @@ -58,18 +54,19 @@ func AssetProofDecoder(r io.Reader, val any, buf *[8]byte, l uint64) error {
return err
}
var proof AssetProof
records := []tlv.Record{
AssetProofVersionRecord(&proof.Version),
AssetProofAssetIDRecord(&proof.TapKey),
AssetProofRecord(&proof.Proof),
}
stream, err := tlv.NewStream(records...)
stream, err := tlv.NewStream(proof.Records()...)
if err != nil {
return err
}
if err := stream.Decode(bytes.NewReader(streamBytes)); err != nil {

err = asset.TlvStrictDecodeP2P(
stream, bytes.NewReader(streamBytes),
KnownAssetProofTypes,
)
if err != nil {
return err
}

*typ = &proof
return nil
}
Expand All @@ -78,11 +75,7 @@ func AssetProofDecoder(r io.Reader, val any, buf *[8]byte, l uint64) error {

func TaprootAssetProofEncoder(w io.Writer, val any, buf *[8]byte) error {
if t, ok := val.(*TaprootAssetProof); ok {
records := []tlv.Record{
TaprootAssetProofVersionRecord(&(*t).Version),
TaprootAssetProofRecord(&(*t).Proof),
}
stream, err := tlv.NewStream(records...)
stream, err := tlv.NewStream((*t).Records()...)
if err != nil {
return err
}
Expand All @@ -106,17 +99,19 @@ func TaprootAssetProofDecoder(r io.Reader, val any, buf *[8]byte,
return err
}
var proof TaprootAssetProof
records := []tlv.Record{
TaprootAssetProofVersionRecord(&proof.Version),
TaprootAssetProofRecord(&proof.Proof),
}
stream, err := tlv.NewStream(records...)
stream, err := tlv.NewStream(proof.Records()...)
if err != nil {
return err
}
if err := stream.Decode(bytes.NewReader(streamBytes)); err != nil {

err = asset.TlvStrictDecodeP2P(
stream, bytes.NewReader(streamBytes),
KnownTaprootAssetProofTypes,
)
if err != nil {
return err
}

*typ = proof
return nil
}
Expand Down
24 changes: 22 additions & 2 deletions commitment/proof.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,15 @@ type AssetProof struct {
TapKey [32]byte
}

// Records returns the encoding/decoding records for the AssetProof.
func (a *AssetProof) Records() []tlv.Record {
return []tlv.Record{
AssetProofVersionRecord(&a.Version),
AssetProofAssetIDRecord(&a.TapKey),
AssetProofRecord(&a.Proof),
}
}

// TaprootAssetProof is the proof used along with an asset commitment leaf to
// arrive at the root of the TapCommitment MS-SMT.
type TaprootAssetProof struct {
Expand All @@ -40,6 +49,14 @@ type TaprootAssetProof struct {
Version TapCommitmentVersion
}

// Records returns the encoding/decoding records for the TaprootAssetProof.
func (t *TaprootAssetProof) Records() []tlv.Record {
return []tlv.Record{
TaprootAssetProofVersionRecord(&t.Version),
TaprootAssetProofRecord(&t.Proof),
}
}

// Proof represents a full commitment proof for a particular `Asset`. It proves
// that an asset does or does not exist within a Taproot Asset commitment.
type Proof struct {
Expand All @@ -63,7 +80,9 @@ func (p Proof) EncodeRecords() []tlv.Record {
if p.AssetProof != nil {
records = append(records, ProofAssetProofRecord(&p.AssetProof))
}
records = append(records, ProofTaprootAssetProofRecord(&p.TaprootAssetProof))
records = append(
records, ProofTaprootAssetProofRecord(&p.TaprootAssetProof),
)
return records
}

Expand All @@ -90,7 +109,8 @@ func (p *Proof) Decode(r io.Reader) error {
if err != nil {
return err
}
return stream.DecodeP2P(r)

return asset.TlvStrictDecodeP2P(stream, r, KnownProofTypes)
}

// DeriveByAssetInclusion derives the Taproot Asset commitment containing the
Expand Down
24 changes: 22 additions & 2 deletions commitment/records.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"bytes"

"github.com/lightninglabs/taproot-assets/asset"
"github.com/lightninglabs/taproot-assets/fn"
"github.com/lightninglabs/taproot-assets/mssmt"
"github.com/lightningnetwork/lnd/tlv"
)
Expand All @@ -20,6 +21,25 @@ const (
ProofTaprootAssetProofType tlv.Type = 2
)

// KnownAssetProofTypes is a set of all known asset proof TLV types. This set
// is asserted to be complete by a check in the BIP test vector unit tests.
var KnownAssetProofTypes = fn.NewSet(
AssetProofVersionType, AssetProofAssetIDType, AssetProofType,
)

// KnownTaprootAssetProofTypes is a set of all known taproot asset proof TLV
// types. This set is asserted to be complete by a check in the BIP test vector
// unit tests.
var KnownTaprootAssetProofTypes = fn.NewSet(
TaprootAssetProofVersionType, TaprootAssetProofType,
)

// KnownProofTypes is a set of all known proof TLV types. This set is asserted
// to be complete by a check in the BIP test vector unit tests.
var KnownProofTypes = fn.NewSet(
ProofAssetProofType, ProofTaprootAssetProofType,
)

func ProofAssetProofRecord(proof **AssetProof) tlv.Record {
sizeFunc := func() uint64 {
var buf bytes.Buffer
Expand All @@ -45,8 +65,8 @@ func ProofTaprootAssetProofRecord(proof *TaprootAssetProof) tlv.Record {
return uint64(len(buf.Bytes()))
}
return tlv.MakeDynamicRecord(
ProofTaprootAssetProofType, proof, sizeFunc, TaprootAssetProofEncoder,
TaprootAssetProofDecoder,
ProofTaprootAssetProofType, proof, sizeFunc,
TaprootAssetProofEncoder, TaprootAssetProofDecoder,
)
}

Expand Down