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

Add multiverse RPC proof courier #473

Merged
merged 13 commits into from
Sep 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions asset/asset.go
Original file line number Diff line number Diff line change
Expand Up @@ -822,6 +822,37 @@ func (a *Asset) IsBurn() bool {
return IsBurnKey(a.ScriptKey.PubKey, a.PrevWitnesses[0])
}

// PrimaryPrevID returns the primary prev ID of an asset. This is the prev ID of
// the first witness, unless the first witness is a split-commitment witness,
// in which case it is the prev ID of the first witness of the root asset.
// The first witness effectively corresponds to the asset's direct lineage.
func (a *Asset) PrimaryPrevID() (*PrevID, error) {
if len(a.PrevWitnesses) == 0 {
return nil, fmt.Errorf("asset missing previous witnesses")
}

// The primary prev ID is stored on the root asset if this asset is a
// split output. We determine whether this asset is a split output by
// inspecting the first previous witness.
primaryWitness := a.PrevWitnesses[0]
isSplitOutput := IsSplitCommitWitness(primaryWitness)

// If this is a split output, then we need to look up the first PrevID
// in the split root asset.
if isSplitOutput {
rootAsset := primaryWitness.SplitCommitment.RootAsset
if len(rootAsset.PrevWitnesses) == 0 {
return nil, fmt.Errorf("asset missing previous " +
"witnesses")
}
return rootAsset.PrevWitnesses[0].PrevID, nil
}

// This asset is not a split output, so we can just return the PrevID
// found in the first witness.
return primaryWitness.PrevID, nil
}

// Copy returns a deep copy of an Asset.
func (a *Asset) Copy() *Asset {
assetCopy := *a
Expand Down
3 changes: 2 additions & 1 deletion cmd/tapcli/universe.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (

tap "github.com/lightninglabs/taproot-assets"
"github.com/lightninglabs/taproot-assets/proof"
"github.com/lightninglabs/taproot-assets/taprpc"
"github.com/lightninglabs/taproot-assets/taprpc/universerpc"
unirpc "github.com/lightninglabs/taproot-assets/taprpc/universerpc"
"github.com/lightningnetwork/lnd/lncfg"
Expand Down Expand Up @@ -417,7 +418,7 @@ func universeProofInsert(ctx *cli.Context) error {
if err != nil {
return err
}
rpcAsset, err := tap.MarshalAsset(
rpcAsset, err := taprpc.MarshalAsset(
ctxc, &assetProof.Asset, false, true, nil,
)
if err != nil {
Expand Down
4 changes: 2 additions & 2 deletions itest/send_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ import (
"github.com/stretchr/testify/require"
)

// testBasicSend tests that we can properly send assets back and forth between
// nodes.
// testBasicSendUnidirectional tests that we can properly send assets back and
// forth between nodes.
func testBasicSendUnidirectional(t *harnessTest) {
var (
ctxb = context.Background()
Expand Down
7 changes: 7 additions & 0 deletions itest/tapd_harness.go
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,13 @@ func newTapdHarness(t *testing.T, ht *harnessTest, cfg tapdConfig,
ReceiverAckTimeout: receiverAckTimeout,
BackoffCfg: backoffCfg,
}

case *UniverseRPCHarness:
finalCfg.DefaultProofCourierAddr = fmt.Sprintf(
"%s://%s", proof.UniverseRpcCourierType,
typedProofCourier.ListenAddr,
)

default:
finalCfg.DefaultProofCourierAddr = ""
finalCfg.HashMailCourier = nil
Expand Down
5 changes: 4 additions & 1 deletion itest/test_harness.go
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ func (h *harnessTest) LogfTimestamped(format string, args ...interface{}) {
}

// shutdown stops both the mock universe and tapd server.
func (h *harnessTest) shutdown(t *testing.T) error {
func (h *harnessTest) shutdown(_ *testing.T) error {
h.universeServer.stop()

if h.proofCourier != nil {
Expand Down Expand Up @@ -284,6 +284,9 @@ func setupHarnesses(t *testing.T, ht *harnessTest,
port := nextAvailablePort()
apHarness := NewApertureHarness(ht.t, port)
proofCourier = &apHarness

case proof.UniverseRpcCourierType:
proofCourier = NewUniverseRPCHarness(t, ht, lndHarness.Bob)
}

// Start the proof courier harness if specified.
Expand Down
5 changes: 5 additions & 0 deletions itest/test_list_on_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,11 @@ var testCases = []*testCase{
test: testBasicSendUnidirectional,
proofCourierType: proof.HashmailCourierType,
},
{
name: "basic send universerpc proof courier",
test: testBasicSendUnidirectional,
proofCourierType: proof.UniverseRpcCourierType,
},
{
name: "resume pending package send",
test: testResumePendingPackageSend,
Expand Down
51 changes: 51 additions & 0 deletions itest/universerpc_harness.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package itest

import (
"testing"

"github.com/lightninglabs/taproot-assets/proof"
"github.com/lightningnetwork/lnd/lntest/node"
"github.com/stretchr/testify/require"
)

// UniverseRPCHarness is an integration testing harness for the universe tap
// service.
type UniverseRPCHarness struct {
// service is the instance of the universe tap service.
service *tapdHarness

// ListenAddr is the address that the service is listening on.
ListenAddr string
}

// NewUniverseRPCHarness creates a new test harness for a universe tap service.
func NewUniverseRPCHarness(t *testing.T, ht *harnessTest,
ffranr marked this conversation as resolved.
Show resolved Hide resolved
lndHarness *node.HarnessNode) *UniverseRPCHarness {

service, err := newTapdHarness(
t, ht, tapdConfig{
NetParams: harnessNetParams,
LndNode: lndHarness,
}, nil, nil, nil,
)
require.NoError(t, err)

return &UniverseRPCHarness{
service: service,
ListenAddr: service.rpcHost(),
}
}

// Start starts the service.
func (h *UniverseRPCHarness) Start(_ chan error) error {
return h.service.start(false)
}

// Stop stops the service.
func (h *UniverseRPCHarness) Stop() error {
return h.service.stop(true)
}

// Ensure that NewUniverseRPCHarness implements the proof.CourierHarness
// interface.
var _ proof.CourierHarness = (*UniverseRPCHarness)(nil)
4 changes: 4 additions & 0 deletions proof/archive.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,10 @@ type Locator struct {
// ScriptKey specifies the script key of the asset to fetch/store. This
// field MUST be specified.
ScriptKey btcec.PublicKey

// OutPoint is the outpoint of the associated asset. This field is
// optional.
OutPoint *wire.OutPoint
}

// Hash returns a SHA256 hash of the bytes serialized locator.
Expand Down
Loading