Skip to content

Commit f7c543d

Browse files
authored
Merge pull request #771 from Roasbeef/v0-3-3-branch
release: create v0.3.3 branch
2 parents 564795a + d36e844 commit f7c543d

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

71 files changed

+4443
-1221
lines changed

fn/func.go

+50
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,18 @@ func All[T any](xs []T, pred func(T) bool) bool {
130130
return true
131131
}
132132

133+
// AllMapItems returns true if the passed predicate returns true for all items
134+
// in the map.
135+
func AllMapItems[T any, K comparable](xs map[K]T, pred func(T) bool) bool {
136+
for i := range xs {
137+
if !pred(xs[i]) {
138+
return false
139+
}
140+
}
141+
142+
return true
143+
}
144+
133145
// Any returns true if the passed predicate returns true for any item in the
134146
// slice.
135147
func Any[T any](xs []T, pred func(T) bool) bool {
@@ -148,6 +160,30 @@ func None[T any](xs []T, pred func(T) bool) bool {
148160
return !Any(xs, pred)
149161
}
150162

163+
// AnyMapItem returns true if the passed predicate returns true for any item in
164+
// the map.
165+
func AnyMapItem[T any, K comparable](xs map[K]T, pred func(T) bool) bool {
166+
for i := range xs {
167+
if pred(xs[i]) {
168+
return true
169+
}
170+
}
171+
172+
return false
173+
}
174+
175+
// NotAny returns true if the passed predicate returns false for all items in
176+
// the slice.
177+
func NotAny[T any](xs []T, pred func(T) bool) bool {
178+
return !Any(xs, pred)
179+
}
180+
181+
// NotAnyMapItem returns true if the passed predicate returns false for all
182+
// items in the map.
183+
func NotAnyMapItem[T any, K comparable](xs map[K]T, pred func(T) bool) bool {
184+
return !AnyMapItem(xs, pred)
185+
}
186+
151187
// Count returns the number of items in the slice that match the predicate.
152188
func Count[T any](xs []T, pred func(T) bool) int {
153189
var count int
@@ -161,6 +197,20 @@ func Count[T any](xs []T, pred func(T) bool) int {
161197
return count
162198
}
163199

200+
// CountMapItems returns the number of items in the map that match the
201+
// predicate.
202+
func CountMapItems[T any, K comparable](xs map[K]T, pred func(T) bool) int {
203+
var count int
204+
205+
for i := range xs {
206+
if pred(xs[i]) {
207+
count++
208+
}
209+
}
210+
211+
return count
212+
}
213+
164214
// First returns the first item in the slice that matches the predicate, or an
165215
// error if none matches.
166216
func First[T any](xs []*T, pred func(*T) bool) (*T, error) {

fn/iter.go

+21-7
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,8 @@ package fn
77
// This function can be used instead of the normal range loop to ensure that a
88
// loop scoping bug isn't introduced.
99
func ForEachErr[T any](s []T, f func(T) error) error {
10-
for _, item := range s {
11-
item := item
12-
13-
if err := f(item); err != nil {
10+
for i := range s {
11+
if err := f(s[i]); err != nil {
1412
return err
1513
}
1614
}
@@ -22,9 +20,17 @@ func ForEachErr[T any](s []T, f func(T) error) error {
2220
// This can be used to ensure that any normal for-loop don't run into bugs due
2321
// to loop variable scoping.
2422
func ForEach[T any](items []T, f func(T)) {
25-
for _, item := range items {
26-
item := item
27-
f(item)
23+
for i := range items {
24+
f(items[i])
25+
}
26+
}
27+
28+
// ForEachMapItem is a generic implementation of a for-each (map with side
29+
// effects). This can be used to ensure that any normal for-loop don't run into
30+
// bugs due to loop variable scoping.
31+
func ForEachMapItem[T any, K comparable](items map[K]T, f func(T)) {
32+
for i := range items {
33+
f(items[i])
2834
}
2935
}
3036

@@ -38,6 +44,14 @@ func Enumerate[T any](items []T, f func(int, T)) {
3844
}
3945
}
4046

47+
// EnumerateMap is a generic enumeration function. The closure will be called
48+
// for each key and item in the passed-in map.
49+
func EnumerateMap[T any, K comparable](items map[K]T, f func(K, T)) {
50+
for key := range items {
51+
f(key, items[key])
52+
}
53+
}
54+
4155
// MakeSlice is a generic function shorthand for making a slice out of a set
4256
// of elements. This can be used to avoid having to specify the type of the
4357
// slice as well as the types of the elements.

itest/addrs_test.go

+90-27
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
tap "github.com/lightninglabs/taproot-assets"
99
"github.com/lightninglabs/taproot-assets/fn"
1010
"github.com/lightninglabs/taproot-assets/internal/test"
11+
"github.com/lightninglabs/taproot-assets/proof"
1112
"github.com/lightninglabs/taproot-assets/tappsbt"
1213
"github.com/lightninglabs/taproot-assets/taprpc"
1314
wrpc "github.com/lightninglabs/taproot-assets/taprpc/assetwalletrpc"
@@ -40,10 +41,6 @@ func testAddresses(t *harnessTest) {
4041
// assets made above.
4142
secondTapd := setupTapdHarness(
4243
t.t, t, t.lndHarness.Bob, t.universeServer,
43-
func(params *tapdHarnessParams) {
44-
params.startupSyncNode = t.tapd
45-
params.startupSyncNumAssets = len(rpcAssets)
46-
},
4744
)
4845
defer func() {
4946
require.NoError(t.t, secondTapd.stop(!*noDelete))
@@ -79,12 +76,6 @@ func testAddresses(t *harnessTest) {
7976
// Eventually the event should be marked as confirmed.
8077
AssertAddrEvent(t.t, secondTapd, addr, 1, statusConfirmed)
8178

82-
// To complete the transfer, we'll export the proof from the
83-
// sender and import it into the receiver for each asset set.
84-
sendProof(
85-
t, t.tapd, secondTapd, addr.ScriptKey, a.AssetGenesis,
86-
)
87-
8879
// Make sure we have imported and finalized all proofs.
8980
AssertNonInteractiveRecvComplete(t.t, secondTapd, idx+1)
9081

@@ -175,10 +166,6 @@ func testMultiAddress(t *harnessTest) {
175166
alice := t.tapd
176167
bob := setupTapdHarness(
177168
t.t, t, t.lndHarness.Bob, t.universeServer,
178-
func(params *tapdHarnessParams) {
179-
params.startupSyncNode = alice
180-
params.startupSyncNumAssets = len(rpcAssets)
181-
},
182169
)
183170
defer func() {
184171
require.NoError(t.t, bob.stop(!*noDelete))
@@ -195,7 +182,12 @@ func testMultiAddress(t *harnessTest) {
195182
func testAddressAssetSyncer(t *harnessTest) {
196183
// We'll kick off the test by making a new node, without hooking it up
197184
// to any existing Universe server.
198-
bob := setupTapdHarness(t.t, t, t.lndHarness.Bob, nil)
185+
bob := setupTapdHarness(
186+
t.t, t, t.lndHarness.Bob, t.universeServer,
187+
func(params *tapdHarnessParams) {
188+
params.noDefaultUniverseSync = true
189+
},
190+
)
199191
defer func() {
200192
require.NoError(t.t, bob.stop(!*noDelete))
201193
}()
@@ -321,8 +313,9 @@ func testAddressAssetSyncer(t *harnessTest) {
321313
restartBobNoUniSync := func(disableSyncer bool) {
322314
require.NoError(t.t, bob.stop(!*noDelete))
323315
bob = setupTapdHarness(
324-
t.t, t, t.lndHarness.Bob, nil,
316+
t.t, t, t.lndHarness.Bob, t.universeServer,
325317
func(params *tapdHarnessParams) {
318+
params.noDefaultUniverseSync = true
326319
params.addrAssetSyncerDisable = disableSyncer
327320
},
328321
)
@@ -436,21 +429,18 @@ func runMultiSendTest(ctxt context.Context, t *harnessTest, alice,
436429

437430
// In order to force a split, we don't try to send the full asset.
438431
const sendAmt = 100
439-
var bobAddresses []*taprpc.Addr
440432
bobAddr1, err := bob.NewAddr(ctxt, &taprpc.NewAddrRequest{
441433
AssetId: genInfo.AssetId,
442434
Amt: sendAmt,
443435
})
444436
require.NoError(t.t, err)
445-
bobAddresses = append(bobAddresses, bobAddr1)
446437
AssertAddrCreated(t.t, bob, mintedAsset, bobAddr1)
447438

448439
bobAddr2, err := bob.NewAddr(ctxt, &taprpc.NewAddrRequest{
449440
AssetId: genInfo.AssetId,
450441
Amt: sendAmt,
451442
})
452443
require.NoError(t.t, err)
453-
bobAddresses = append(bobAddresses, bobAddr2)
454444
AssertAddrCreated(t.t, bob, mintedAsset, bobAddr2)
455445

456446
// To test that Alice can also receive to multiple addresses in a single
@@ -492,14 +482,6 @@ func runMultiSendTest(ctxt context.Context, t *harnessTest, alice,
492482
// this point, so the status should go to completed directly.
493483
AssertAddrEventByStatus(t.t, alice, statusCompleted, numRuns*2)
494484

495-
// To complete the transfer, we'll export the proof from the sender and
496-
// import it into the receiver for each asset set. This should not be
497-
// necessary for the sends to Alice, as she is both the sender and
498-
// receiver and should detect the local proof once it's written to disk.
499-
for i := range bobAddresses {
500-
sendProof(t, alice, bob, bobAddresses[i].ScriptKey, genInfo)
501-
}
502-
503485
// Make sure we have imported and finalized all proofs.
504486
AssertNonInteractiveRecvComplete(t.t, bob, numRuns*2)
505487
AssertNonInteractiveRecvComplete(t.t, alice, numRuns*2)
@@ -531,6 +513,8 @@ func runMultiSendTest(ctxt context.Context, t *harnessTest, alice,
531513
require.NoError(t.t, err)
532514
}
533515

516+
// sendProof manually exports a proof from the given source node and imports it
517+
// using the development only ImportProof RPC on the destination node.
534518
func sendProof(t *harnessTest, src, dst *tapdHarness, scriptKey []byte,
535519
genInfo *taprpc.GenesisInfo) *tapdevrpc.ImportProofResponse {
536520

@@ -562,6 +546,85 @@ func sendProof(t *harnessTest, src, dst *tapdHarness, scriptKey []byte,
562546
return importResp
563547
}
564548

549+
// sendProofUniRPC manually exports a proof from the given source node and
550+
// imports it using the universe related InsertProof RPC on the destination
551+
// node.
552+
func sendProofUniRPC(t *harnessTest, src, dst *tapdHarness, scriptKey []byte,
553+
genInfo *taprpc.GenesisInfo) *unirpc.AssetProofResponse {
554+
555+
ctxb := context.Background()
556+
557+
var proofResp *taprpc.ProofFile
558+
waitErr := wait.NoError(func() error {
559+
resp, err := src.ExportProof(ctxb, &taprpc.ExportProofRequest{
560+
AssetId: genInfo.AssetId,
561+
ScriptKey: scriptKey,
562+
})
563+
if err != nil {
564+
return err
565+
}
566+
567+
proofResp = resp
568+
return nil
569+
}, defaultWaitTimeout)
570+
require.NoError(t.t, waitErr)
571+
572+
t.Logf("Importing proof %x using InsertProof", proofResp.RawProofFile)
573+
574+
f := proof.File{}
575+
err := f.Decode(bytes.NewReader(proofResp.RawProofFile))
576+
require.NoError(t.t, err)
577+
578+
lastProof, err := f.LastProof()
579+
require.NoError(t.t, err)
580+
581+
var lastProofBytes bytes.Buffer
582+
err = lastProof.Encode(&lastProofBytes)
583+
require.NoError(t.t, err)
584+
asset := lastProof.Asset
585+
586+
proofType := universe.ProofTypeTransfer
587+
if asset.IsGenesisAsset() {
588+
proofType = universe.ProofTypeIssuance
589+
}
590+
591+
uniID := universe.Identifier{
592+
AssetID: asset.ID(),
593+
ProofType: proofType,
594+
}
595+
if asset.GroupKey != nil {
596+
uniID.GroupKey = &asset.GroupKey.GroupPubKey
597+
}
598+
599+
rpcUniID, err := tap.MarshalUniID(uniID)
600+
require.NoError(t.t, err)
601+
602+
outpoint := &unirpc.Outpoint{
603+
HashStr: lastProof.AnchorTx.TxHash().String(),
604+
Index: int32(lastProof.InclusionProof.OutputIndex),
605+
}
606+
607+
importResp, err := dst.InsertProof(ctxb, &unirpc.AssetProof{
608+
Key: &unirpc.UniverseKey{
609+
Id: rpcUniID,
610+
LeafKey: &unirpc.AssetKey{
611+
Outpoint: &unirpc.AssetKey_Op{
612+
Op: outpoint,
613+
},
614+
ScriptKey: &unirpc.AssetKey_ScriptKeyBytes{
615+
ScriptKeyBytes: scriptKey,
616+
},
617+
},
618+
},
619+
AssetLeaf: &unirpc.AssetLeaf{
620+
Proof: lastProofBytes.Bytes(),
621+
},
622+
})
623+
require.NoError(t.t, err)
624+
625+
return importResp
626+
}
627+
565628
// sendAssetsToAddr spends the given input asset and sends the amount specified
566629
// in the address to the Taproot output derived from the address.
567630
func sendAssetsToAddr(t *harnessTest, sender *tapdHarness,

itest/aperture_harness.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ type ApertureHarness struct {
2727

2828
// NewApertureHarness creates a new instance of the aperture service. It returns
2929
// a harness which includes useful values for testing.
30-
func NewApertureHarness(t *testing.T, port int) ApertureHarness {
30+
func NewApertureHarness(t *testing.T, port int) *ApertureHarness {
3131
// Create a temporary directory for the aperture service to use.
3232
baseDir := filepath.Join(t.TempDir(), "aperture")
3333
err := os.MkdirAll(baseDir, os.ModePerm)
@@ -55,7 +55,7 @@ func NewApertureHarness(t *testing.T, port int) ApertureHarness {
5555
}
5656
service := aperture.NewAperture(cfg)
5757

58-
return ApertureHarness{
58+
return &ApertureHarness{
5959
ListenAddr: listenAddr,
6060
Service: service,
6161
}

itest/assertions.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -870,7 +870,7 @@ func AssertBalanceByID(t *testing.T, client taprpc.TaprootAssetsClient,
870870
}
871871

872872
require.True(t, ok)
873-
require.Equal(t, uint64(amt), uint64(balance.Balance))
873+
require.Equal(t, amt, balance.Balance)
874874
}
875875

876876
// AssertBalanceByGroup asserts that the balance of a single asset group

itest/collectible_split_test.go

-4
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,6 @@ func testCollectibleSend(t *harnessTest) {
5353
// serve as the node which'll receive the assets.
5454
secondTapd := setupTapdHarness(
5555
t.t, t, t.lndHarness.Bob, t.universeServer,
56-
func(params *tapdHarnessParams) {
57-
params.startupSyncNode = t.tapd
58-
params.startupSyncNumAssets = len(rpcAssets)
59-
},
6056
)
6157
defer func() {
6258
require.NoError(t.t, secondTapd.stop(!*noDelete))

itest/full_value_split_test.go

+4-8
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,6 @@ func testFullValueSend(t *harnessTest) {
3333
// serve as the node which'll receive the assets.
3434
secondTapd := setupTapdHarness(
3535
t.t, t, t.lndHarness.Bob, t.universeServer,
36-
func(params *tapdHarnessParams) {
37-
params.startupSyncNode = t.tapd
38-
params.startupSyncNumAssets = len(rpcAssets)
39-
},
4036
)
4137
defer func() {
4238
require.NoError(t.t, secondTapd.stop(!*noDelete))
@@ -88,8 +84,8 @@ func runFullValueSendTests(ctxt context.Context, t *harnessTest, alice,
8884
[]uint64{0, fullAmount}, senderTransferIdx,
8985
senderTransferIdx+1,
9086
)
91-
_ = sendProof(
92-
t, alice, bob, receiverAddr.ScriptKey, genInfo,
87+
AssertNonInteractiveRecvComplete(
88+
t.t, bob, senderTransferIdx+1,
9389
)
9490
senderTransferIdx++
9591
} else {
@@ -108,8 +104,8 @@ func runFullValueSendTests(ctxt context.Context, t *harnessTest, alice,
108104
genInfo.AssetId, []uint64{0, fullAmount},
109105
receiverTransferIdx, receiverTransferIdx+1,
110106
)
111-
_ = sendProof(
112-
t, bob, alice, receiverAddr.ScriptKey, genInfo,
107+
AssertNonInteractiveRecvComplete(
108+
t.t, alice, receiverTransferIdx+1,
113109
)
114110
receiverTransferIdx++
115111
}

0 commit comments

Comments
 (0)