Skip to content

Commit

Permalink
Merge remote-tracking branch 'altafan/spendable-change-vtxo' into deb…
Browse files Browse the repository at this point in the history
…ug-round-musig-failed
  • Loading branch information
louisinger committed Sep 19, 2024
2 parents 0dc685f + 0096767 commit 0d3069e
Show file tree
Hide file tree
Showing 19 changed files with 222 additions and 235 deletions.
48 changes: 0 additions & 48 deletions common/bitcointree/descriptor.go

This file was deleted.

14 changes: 2 additions & 12 deletions common/bitcointree/vtxo.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,7 @@ func (v *DefaultVtxoScript) ToDescriptor() string {
}

func (v *DefaultVtxoScript) FromDescriptor(desc string) error {
taprootDesc, err := descriptor.ParseTaprootDescriptor(desc)
if err != nil {
return err
}

owner, asp, exitDelay, err := descriptor.ParseDefaultVtxoDescriptor(*taprootDesc)
owner, asp, exitDelay, err := descriptor.ParseDefaultVtxoDescriptor(desc)
if err != nil {
return err
}
Expand Down Expand Up @@ -138,12 +133,7 @@ func (v *ReversibleVtxoScript) ToDescriptor() string {
}

func (v *ReversibleVtxoScript) FromDescriptor(desc string) error {
taprootDesc, err := descriptor.ParseTaprootDescriptor(desc)
if err != nil {
return err
}

owner, sender, asp, exitDelay, err := descriptor.ParseReversibleVtxoDescriptor(*taprootDesc)
owner, sender, asp, exitDelay, err := descriptor.ParseReversibleVtxoDescriptor(desc)
if err != nil {
return err
}
Expand Down
14 changes: 12 additions & 2 deletions common/descriptor/ark.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,13 @@ const DefaultVtxoDescriptorTemplate = "tr(%s,{ and(pk(%s), pk(%s)), and(older(%d
const ReversibleVtxoScriptTemplate = "tr(%s,{ { and(pk(%s), pk(%s)), and(older(%d), pk(%s)) }, and(pk(%s), pk(%s)) })"

func ParseReversibleVtxoDescriptor(
desc TaprootDescriptor,
descriptor string,
) (user, sender, asp *secp256k1.PublicKey, timeout uint, err error) {
desc, err := ParseTaprootDescriptor(descriptor)
if err != nil {
return nil, nil, nil, 0, err
}

if len(desc.ScriptTree) != 3 {
return nil, nil, nil, 0, errors.New("not a reversible vtxo script descriptor")
}
Expand Down Expand Up @@ -92,8 +97,13 @@ func ParseReversibleVtxoDescriptor(
}

func ParseDefaultVtxoDescriptor(
desc TaprootDescriptor,
descriptor string,
) (user, asp *secp256k1.PublicKey, timeout uint, err error) {
desc, err := ParseTaprootDescriptor(descriptor)
if err != nil {
return nil, nil, 0, err
}

if len(desc.ScriptTree) != 2 {
return nil, nil, 0, errors.New("not a default vtxo script descriptor")
}
Expand Down
52 changes: 0 additions & 52 deletions common/tree/descriptor.go

This file was deleted.

7 changes: 1 addition & 6 deletions common/tree/vtxo.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,7 @@ func (v *DefaultVtxoScript) ToDescriptor() string {
}

func (v *DefaultVtxoScript) FromDescriptor(desc string) error {
taprootDesc, err := descriptor.ParseTaprootDescriptor(desc)
if err != nil {
return err
}

owner, asp, exitDelay, err := descriptor.ParseDefaultVtxoDescriptor(*taprootDesc)
owner, asp, exitDelay, err := descriptor.ParseDefaultVtxoDescriptor(desc)
if err != nil {
return err
}
Expand Down
20 changes: 0 additions & 20 deletions pkg/client-sdk/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -231,26 +231,6 @@ func (a *arkClient) Receive(ctx context.Context) (string, string, error) {
return offchainAddr, boardingAddr, nil
}

func (a *arkClient) ListVtxos(
ctx context.Context,
) (spendableVtxos, spentVtxos []client.Vtxo, err error) {
offchainAddrs, _, _, err := a.wallet.GetAddresses(ctx)
if err != nil {
return
}

for _, addr := range offchainAddrs {
spendable, spent, err := a.client.ListVtxos(ctx, addr)
if err != nil {
return nil, nil, err
}
spendableVtxos = append(spendableVtxos, spendable...)
spentVtxos = append(spentVtxos, spent...)
}

return
}

func (a *arkClient) ping(
ctx context.Context, paymentID string,
) func() {
Expand Down
20 changes: 20 additions & 0 deletions pkg/client-sdk/covenant_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,26 @@ func LoadCovenantClientWithWallet(
}, nil
}

func (a *covenantArkClient) ListVtxos(
ctx context.Context,
) (spendableVtxos, spentVtxos []client.Vtxo, err error) {
offchainAddrs, _, _, err := a.wallet.GetAddresses(ctx)
if err != nil {
return
}

for _, addr := range offchainAddrs {
spendable, spent, err := a.client.ListVtxos(ctx, addr)
if err != nil {
return nil, nil, err
}
spendableVtxos = append(spendableVtxos, spendable...)
spentVtxos = append(spentVtxos, spent...)
}

return
}

func (a *covenantArkClient) Balance(
ctx context.Context, computeVtxoExpiration bool,
) (*Balance, error) {
Expand Down
55 changes: 53 additions & 2 deletions pkg/client-sdk/covenantless_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,57 @@ func LoadCovenantlessClientWithWallet(
}, nil
}

func (a *covenantlessArkClient) ListVtxos(
ctx context.Context,
) (spendableVtxos, spentVtxos []client.Vtxo, err error) {
offchainAddrs, _, _, err := a.wallet.GetAddresses(ctx)
if err != nil {
return
}

// The ASP returns the vtxos sent to others via async payments as spendable
// because they are actually revertable. Since we do not provide any revert
// feature, we want to ignore them.
// To understand if the output of a redeem tx is sent or received we look at
// the inputs and check if they are owned by us.
// The auxiliary variables below are used to make these checks in an
// efficient way.
indexedSpentVtxos := make(map[string]client.Vtxo)
pendingVtxos := make([]client.Vtxo, 0)
keyTempl := "%s:%d"
for _, addr := range offchainAddrs {
spendable, spent, err := a.client.ListVtxos(ctx, addr)
if err != nil {
return nil, nil, err
}
for _, v := range spendable {
if !v.Pending {
spendableVtxos = append(spendableVtxos, v)
continue
}
pendingVtxos = append(pendingVtxos, v)
}
for _, v := range spent {
indexedSpentVtxos[fmt.Sprintf(keyTempl, v.Txid, v.VOut)] = v
spentVtxos = append(spentVtxos, v)
}
}

for _, vtxo := range pendingVtxos {
ptx, err := psbt.NewFromRawBytes(strings.NewReader(vtxo.RedeemTx), true)
if err != nil {
return nil, nil, err
}
input := ptx.UnsignedTx.TxIn[0].PreviousOutPoint
key := fmt.Sprintf(keyTempl, input.Hash.String(), input.Index)
if _, ok := indexedSpentVtxos[key]; !ok {
spendableVtxos = append(spendableVtxos, vtxo)
}
}

return
}

func (a *covenantlessArkClient) Balance(
ctx context.Context, computeVtxoExpiration bool,
) (*Balance, error) {
Expand Down Expand Up @@ -1803,9 +1854,9 @@ func (a *covenantlessArkClient) getClaimableBoardingUtxos(ctx context.Context) (
}

func (a *covenantlessArkClient) getVtxos(
ctx context.Context, addr string, computeVtxoExpiration bool,
ctx context.Context, _ string, computeVtxoExpiration bool,
) ([]client.Vtxo, []client.Vtxo, error) {
vtxos, _, err := a.client.ListVtxos(ctx, addr)
vtxos, _, err := a.ListVtxos(ctx)
if err != nil {
return nil, nil, err
}
Expand Down
10 changes: 9 additions & 1 deletion server/internal/core/application/covenantless.go
Original file line number Diff line number Diff line change
Expand Up @@ -263,20 +263,25 @@ func (s *covenantlessService) CompleteAsyncPayment(
vtxos := make([]domain.Vtxo, 0, len(asyncPayData.receivers))

for outIndex, out := range redeemPtx.UnsignedTx.TxOut {
desc := asyncPayData.receivers[outIndex].Descriptor
_, _, _, _, err := descriptor.ParseReversibleVtxoDescriptor(desc)
isPending := err == nil

vtxos = append(vtxos, domain.Vtxo{
VtxoKey: domain.VtxoKey{
Txid: redeemTxid,
VOut: uint32(outIndex),
},
Receiver: domain.Receiver{
Descriptor: asyncPayData.receivers[outIndex].Descriptor,
Descriptor: desc,
Amount: uint64(out.Value),
},
ExpireAt: asyncPayData.expireAt,
AsyncPayment: &domain.AsyncPaymentTxs{
RedeemTx: redeemTx,
UnconditionalForfeitTxs: unconditionalForfeitTxs,
},
Pending: isPending,
})
}

Expand Down Expand Up @@ -332,6 +337,9 @@ func (s *covenantlessService) CreateAsyncPayment(
if vtxo.Swept {
return "", nil, fmt.Errorf("all vtxos must be swept")
}
if vtxo.Pending {
return "", nil, fmt.Errorf("all vtxos must be claimed")
}

if vtxo.ExpireAt < expiration {
expiration = vtxo.ExpireAt
Expand Down
1 change: 1 addition & 0 deletions server/internal/core/domain/payment.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ type Vtxo struct {
Swept bool
ExpireAt int64
AsyncPayment *AsyncPaymentTxs // nil if not async vtxo
Pending bool
}

type AsyncPaymentTxs struct {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE vtxo DROP COLUMN pending;
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
ALTER TABLE vtxo ADD COLUMN pending BOOLEAN;

DROP VIEW payment_vtxo_vw;
DROP VIEW payment_receiver_vw;

CREATE VIEW payment_vtxo_vw AS SELECT vtxo.*
FROM payment
LEFT OUTER JOIN vtxo
ON payment.id=vtxo.payment_id;

CREATE VIEW payment_receiver_vw AS SELECT receiver.*
FROM payment
LEFT OUTER JOIN receiver
ON payment.id=receiver.payment_id;

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 0d3069e

Please sign in to comment.