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

feat: deferred claims #327

Draft
wants to merge 3 commits into
base: master
Choose a base branch
from
Draft
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
2 changes: 1 addition & 1 deletion boltz/btc.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ func constructBtcTransaction(network *Network, outputs []OutputDetails, outValue

for _, output := range outputs {
// Set the highest timeout block height as locktime
if !output.Cooperative {
if !output.Cooperative && output.IsRefund() {
if output.TimeoutBlockHeight > transaction.LockTime {
transaction.LockTime = output.TimeoutBlockHeight
}
Expand Down
2 changes: 1 addition & 1 deletion boltz/liquid.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ func constructLiquidTransaction(network *Network, outputs []OutputDetails, outVa
TxIndex: output.Vout,
Sequence: 0xfffffffd,
}
if !output.Cooperative {
if !output.Cooperative && output.IsRefund() {
input.HeightLock = output.TimeoutBlockHeight
}

Expand Down
64 changes: 35 additions & 29 deletions boltz/transaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,20 +76,27 @@ type OutputResult struct {
Fee uint64
}

type Results map[string]OutputResult
type ConstructResult struct {
Transaction Transaction
Details map[string]OutputResult
Err error
TransactionId string
}

func (results Results) SetErr(id string, err error) {
if results[id].Err == nil {
results[id] = OutputResult{Err: err}
func (result ConstructResult) SwapResult(id string) OutputResult {
details := result.Details[id]
if result.Err != nil && details.Err == nil {
return OutputResult{Err: result.Err}
}
return details
}

func ConstructTransaction(network *Network, currency Currency, outputs []OutputDetails, satPerVbyte float64, boltzApi *Api) (Transaction, Results, error) {
func ConstructTransaction(network *Network, currency Currency, outputs []OutputDetails, satPerVbyte float64, boltzApi *Api) ConstructResult {
construct := constructBtcTransaction
if currency == CurrencyLiquid {
construct = constructLiquidTransaction
}
results := make(Results, len(outputs))
swapErrors := make(map[string]OutputResult, len(outputs))

getOutValues := func(fee uint64) map[string]uint64 {
outValues := make(map[string]uint64)
Expand All @@ -104,31 +111,32 @@ func ConstructTransaction(network *Network, currency Currency, outputs []OutputD
feeRemainder = 0

value, err := output.LockupTransaction.VoutValue(output.Vout)
if err != nil {
results.SetErr(output.SwapId, err)
continue
if err == nil {
if value < output.Fee {
err = fmt.Errorf("value less than fee: %d < %d", value, output.Fee)
}
}
if value < output.Fee {
results.SetErr(output.SwapId, fmt.Errorf("value less than fee: %d < %d", value, output.Fee))
continue
if err != nil {
swapErrors[output.SwapId] = OutputResult{Err: err}
} else {
swapErrors[output.SwapId] = OutputResult{Fee: output.Fee}
outValues[output.Address] += value - output.Fee
}

results[output.SwapId] = OutputResult{Fee: output.Fee}
outValues[output.Address] += value - output.Fee
}
return outValues
}

noFeeTransaction, err := construct(network, outputs, getOutValues(0))
if err != nil {
return nil, nil, err
return ConstructResult{Err: err}
}

fee := uint64(math.Ceil(float64(noFeeTransaction.VSize()) * satPerVbyte))

transaction, err := construct(network, outputs, getOutValues(fee))
if err != nil {
return nil, nil, err
return ConstructResult{Err: err}
}

var valid []OutputDetails
Expand Down Expand Up @@ -209,7 +217,7 @@ func ConstructTransaction(network *Network, currency Currency, outputs []OutputD
}()
if err != nil {
if output.IsRefund() {
results[output.SwapId] = OutputResult{Err: err}
swapErrors[output.SwapId] = OutputResult{Err: err}
reconstruct = true
} else {
nonCoop := outputs[i]
Expand All @@ -222,20 +230,18 @@ func ConstructTransaction(network *Network, currency Currency, outputs []OutputD
}
}

if len(valid) == 0 {
return nil, results, fmt.Errorf("all outputs invalid")
}

if reconstruct {
transaction, newResults, err := ConstructTransaction(network, currency, valid, satPerVbyte, boltzApi)
if err != nil {
return nil, nil, err
if reconstruct && len(valid) > 0 {
newResult := ConstructTransaction(network, currency, valid, satPerVbyte, boltzApi)
if newResult.Err != nil {
return newResult
}
for id, result := range newResults {
results[id] = result
for id, result := range swapErrors {
if _, ok := newResult.Details[id]; !ok {
newResult.Details[id] = result
}
}
return transaction, results, nil
return newResult
}

return transaction, results, err
return ConstructResult{Transaction: transaction, Details: swapErrors, TransactionId: transaction.Hash()}
}
Loading
Loading