CompleteAsyncPayment: validate signatures and transactions (#298)

This commit is contained in:
Louis Singer
2024-09-10 19:21:54 +02:00
committed by GitHub
parent 0fb34cb13d
commit 1387c8da7a
8 changed files with 209 additions and 72 deletions

View File

@@ -38,22 +38,51 @@ func NewTxBuilder(
return &txBuilder{wallet, net, roundLifetime, exitDelay, boardingExitDelay}
}
func (b *txBuilder) VerifyForfeitTx(tx string) (bool, string, error) {
func (b *txBuilder) VerifyTapscriptPartialSigs(tx string) (bool, string, error) {
ptx, _ := psbt.NewFromRawBytes(strings.NewReader(tx), true)
txid := ptx.UnsignedTx.TxHash().String()
txid := ptx.UnsignedTx.TxID()
for index, input := range ptx.Inputs {
// TODO (@louisinger): verify control block
for _, tapScriptSig := range input.TaprootScriptSpendSig {
preimage, err := b.getTaprootPreimage(
tx,
index,
input.TaprootLeafScript[0].Script,
)
if err != nil {
return false, txid, err
}
if len(input.TaprootLeafScript) == 0 {
continue
}
if input.WitnessUtxo == nil {
return false, txid, fmt.Errorf("missing witness utxo for input %d, cannot verify signature", index)
}
// verify taproot leaf script
tapLeaf := input.TaprootLeafScript[0]
if len(tapLeaf.ControlBlock) == 0 {
return false, txid, fmt.Errorf("missing control block for input %d", index)
}
controlBlock, err := txscript.ParseControlBlock(tapLeaf.ControlBlock)
if err != nil {
return false, txid, err
}
rootHash := controlBlock.RootHash(tapLeaf.Script)
tapKeyFromControlBlock := txscript.ComputeTaprootOutputKey(bitcointree.UnspendableKey(), rootHash[:])
pkscript, err := p2trScript(tapKeyFromControlBlock)
if err != nil {
return false, txid, err
}
if !bytes.Equal(pkscript, input.WitnessUtxo.PkScript) {
return false, txid, fmt.Errorf("invalid control block for input %d", index)
}
preimage, err := b.getTaprootPreimage(
tx,
index,
tapLeaf.Script,
)
if err != nil {
return false, txid, err
}
for _, tapScriptSig := range input.TaprootScriptSpendSig {
sig, err := schnorr.ParseSignature(tapScriptSig.Signature)
if err != nil {
return false, txid, err
@@ -64,15 +93,13 @@ func (b *txBuilder) VerifyForfeitTx(tx string) (bool, string, error) {
return false, txid, err
}
if sig.Verify(preimage, pubkey) {
return true, txid, nil
} else {
if !sig.Verify(preimage, pubkey) {
return false, txid, fmt.Errorf("invalid signature for tx %s", txid)
}
}
}
return false, txid, nil
return true, txid, nil
}
func (b *txBuilder) FinalizeAndExtractForfeit(tx string) (string, error) {
@@ -359,8 +386,7 @@ func (b *txBuilder) BuildAsyncPaymentTransactions(
return nil, err
}
// TODO generate a fresh new address to get the forfeit funds
aspScript, err := p2trScript(aspPubKey, b.onchainNetwork())
aspScript, err := p2trScript(aspPubKey)
if err != nil {
return nil, err
}
@@ -494,8 +520,13 @@ func (b *txBuilder) BuildAsyncPaymentTransactions(
})
}
sequences := make([]uint32, len(ins))
for i := range sequences {
sequences[i] = wire.MaxTxInSequenceNum
}
redeemPtx, err := psbt.New(
ins, outs, 2, 0, []uint32{wire.MaxTxInSequenceNum},
ins, outs, 2, 0, sequences,
)
if err != nil {
return nil, err
@@ -1087,8 +1118,7 @@ func (b *txBuilder) minRelayFeeForfeitTx() (uint64, error) {
func (b *txBuilder) createForfeitTxs(
aspPubkey *secp256k1.PublicKey, payments []domain.Payment, connectors []*psbt.Packet, feeAmount uint64,
) ([]string, error) {
// TODO generate a fresh new address to receive the forfeited funds
aspScript, err := p2trScript(aspPubkey, b.onchainNetwork())
aspScript, err := p2trScript(aspPubkey)
if err != nil {
return nil, err
}