Files
ark/server/internal/infrastructure/tx-builder/covenant/utils.go
Louis Singer 10ef0dbffa Add reversible policy to pending vtxos (#311)
* [server] descriptor-based vtxo script

* [server] fix unit tests

* [sdk] descriptor based vtxo

* empty config check & version flag support

* fix: empty config check & version flag support (#309)

* fix

* [sdk] several fixes

* [sdk][server] several fixes

* [common][sdk] add reversible VtxoScript type, use it in async payment

* [common] improve parser

* [common] fix reversible vtxo parser

* [sdk] remove logs

* fix forfeit map

* remove debug log

* [sdk] do not allow reversible vtxo script in case of self-transfer

* remove signing pubkey

* remove signer public key, craft forfeit txs client side

* go work sync

* fix linter errors

* rename MakeForfeitTxs to BuildForfeitTxs

* fix conflicts

* fix tests

* comment VtxoScript type

* revert ROUND_INTERVAL value

---------

Co-authored-by: Pietralberto Mazza <18440657+altafan@users.noreply.github.com>
Co-authored-by: sekulicd <sekula87@gmail.com>
2024-09-19 10:01:33 +02:00

153 lines
3.5 KiB
Go

package txbuilder
import (
"encoding/hex"
"fmt"
"github.com/ark-network/ark/common/tree"
"github.com/ark-network/ark/server/internal/core/domain"
"github.com/ark-network/ark/server/internal/core/ports"
"github.com/btcsuite/btcd/txscript"
"github.com/decred/dcrd/dcrec/secp256k1/v4"
"github.com/vulpemventures/go-elements/address"
"github.com/vulpemventures/go-elements/elementsutil"
"github.com/vulpemventures/go-elements/network"
"github.com/vulpemventures/go-elements/payment"
"github.com/vulpemventures/go-elements/psetv2"
"github.com/vulpemventures/go-elements/transaction"
)
func p2wpkhScript(publicKey *secp256k1.PublicKey, net *network.Network) ([]byte, error) {
payment := payment.FromPublicKey(publicKey, net, nil)
addr, err := payment.WitnessPubKeyHash()
if err != nil {
return nil, err
}
return address.ToOutputScript(addr)
}
func getTxid(txStr string) (string, error) {
pset, err := psetv2.NewPsetFromBase64(txStr)
if err != nil {
return "", err
}
return getPsetId(pset)
}
func getPsetId(pset *psetv2.Pset) (string, error) {
utx, err := pset.UnsignedTx()
if err != nil {
return "", err
}
return utx.TxHash().String(), nil
}
func getOnchainReceivers(
payments []domain.Payment,
) []domain.Receiver {
receivers := make([]domain.Receiver, 0)
for _, payment := range payments {
for _, receiver := range payment.Receivers {
if receiver.IsOnchain() {
receivers = append(receivers, receiver)
}
}
}
return receivers
}
func getOffchainReceivers(
payments []domain.Payment,
) ([]tree.Receiver, error) {
receivers := make([]tree.Receiver, 0)
for _, payment := range payments {
for _, receiver := range payment.Receivers {
if !receiver.IsOnchain() {
vtxoScript, err := tree.ParseVtxoScript(receiver.Descriptor)
if err != nil {
return nil, err
}
receivers = append(receivers, tree.Receiver{
Script: vtxoScript,
Amount: receiver.Amount,
})
}
}
}
return receivers, nil
}
func toWitnessUtxo(in ports.TxInput) (*transaction.TxOutput, error) {
valueBytes, err := elementsutil.ValueToBytes(in.GetValue())
if err != nil {
return nil, fmt.Errorf("failed to convert value to bytes: %s", err)
}
assetBytes, err := elementsutil.AssetHashToBytes(in.GetAsset())
if err != nil {
return nil, fmt.Errorf("failed to convert asset to bytes: %s", err)
}
scriptBytes, err := hex.DecodeString(in.GetScript())
if err != nil {
return nil, fmt.Errorf("failed to decode script: %s", err)
}
return transaction.NewTxOutput(assetBytes, valueBytes, scriptBytes), nil
}
func countSpentVtxos(payments []domain.Payment) uint64 {
var sum uint64
for _, payment := range payments {
sum += uint64(len(payment.Inputs))
}
return sum
}
func addInputs(
updater *psetv2.Updater,
inputs []ports.TxInput,
) error {
for _, in := range inputs {
inputArg := psetv2.InputArgs{
Txid: in.GetTxid(),
TxIndex: in.GetIndex(),
}
witnessUtxo, err := toWitnessUtxo(in)
if err != nil {
return err
}
if err := updater.AddInputs([]psetv2.InputArgs{inputArg}); err != nil {
return err
}
index := int(updater.Pset.Global.InputCount) - 1
if err := updater.AddInWitnessUtxo(index, witnessUtxo); err != nil {
return err
}
if err := updater.AddInSighashType(index, txscript.SigHashAll); err != nil {
return err
}
}
return nil
}
func isOnchainOnly(payments []domain.Payment) bool {
for _, p := range payments {
for _, r := range p.Receivers {
if !r.IsOnchain() {
return false
}
}
}
return true
}