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

client/asset/zec: separate Zcash wallet #2553

Merged
merged 5 commits into from
Nov 19, 2023
Merged
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
1,972 changes: 432 additions & 1,540 deletions client/asset/btc/btc.go

Large diffs are not rendered by default.

229 changes: 114 additions & 115 deletions client/asset/btc/btc_test.go

Large diffs are not rendered by default.

70 changes: 35 additions & 35 deletions client/asset/btc/coin_selection.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ import (
// enough func will return a non-zero excess value. Otherwise, the enough func
// will always return 0, leaving only unselected UTXOs to cover any required
// reserves.
func sendEnough(amt, feeRate uint64, subtract bool, baseTxSize uint64, segwit, reportChange bool) func(inputSize, sum uint64) (bool, uint64) {
return func(inputSize, sum uint64) (bool, uint64) {
func sendEnough(amt, feeRate uint64, subtract bool, baseTxSize uint64, segwit, reportChange bool) EnoughFunc {
return func(_, inputSize, sum uint64) (bool, uint64) {
txFee := (baseTxSize + inputSize) * feeRate
req := amt
if !subtract { // add the fee to required
Expand All @@ -45,8 +45,8 @@ func sendEnough(amt, feeRate uint64, subtract bool, baseTxSize uint64, segwit, r
// enough func will return a non-zero excess value reflecting this potential
// spit tx change. Otherwise, the enough func will always return 0, leaving
// only unselected UTXOs to cover any required reserves.
func orderEnough(val, lots, feeRate, initTxSizeBase, initTxSize uint64, segwit, reportChange bool) func(inputsSize, sum uint64) (bool, uint64) {
return func(inputsSize, sum uint64) (bool, uint64) {
func orderEnough(val, lots, feeRate, initTxSizeBase, initTxSize uint64, segwit, reportChange bool) EnoughFunc {
return func(_, inputsSize, sum uint64) (bool, uint64) {
reqFunds := calc.RequiredOrderFundsAlt(val, inputsSize, lots, initTxSizeBase, initTxSize, feeRate)
if sum >= reqFunds {
excess := sum - reqFunds
Expand All @@ -62,22 +62,22 @@ func orderEnough(val, lots, feeRate, initTxSizeBase, initTxSize uint64, segwit,
// reserveEnough generates a function that can be used as the enough argument
// to the fund method. The function returns true if sum is greater than equal
// to amt.
func reserveEnough(amt uint64) func(_, sum uint64) (bool, uint64) {
return func(_, sum uint64) (bool, uint64) {
func reserveEnough(amt uint64) EnoughFunc {
return func(_, _, sum uint64) (bool, uint64) {
return sum >= amt, 0
}
}

func sumUTXOSize(set []*compositeUTXO) (tot uint64) {
func sumUTXOSize(set []*CompositeUTXO) (tot uint64) {
for _, utxo := range set {
tot += uint64(utxo.input.VBytes())
tot += uint64(utxo.Input.VBytes())
}
return tot
}

func sumUTXOs(set []*compositeUTXO) (tot uint64) {
func SumUTXOs(set []*CompositeUTXO) (tot uint64) {
for _, utxo := range set {
tot += utxo.amount
tot += utxo.Amount
}
return tot
}
Expand All @@ -88,14 +88,14 @@ func sumUTXOs(set []*compositeUTXO) (tot uint64) {
// involves two passes over the UTXOs. The first pass randomly selects
// each UTXO with 50% probability. Then, the second pass selects any
// unused UTXOs until the total value is enough.
func subsetWithLeastOverFund(enough func(uint64, uint64) (bool, uint64), maxFund uint64, utxos []*compositeUTXO) []*compositeUTXO {
func subsetWithLeastOverFund(enough EnoughFunc, maxFund uint64, utxos []*CompositeUTXO) []*CompositeUTXO {
best := uint64(1 << 62)
var bestIncluded []bool
bestNumIncluded := 0

rnd := rand.New(rand.NewSource(time.Now().Unix()))

shuffledUTXOs := make([]*compositeUTXO, len(utxos))
shuffledUTXOs := make([]*CompositeUTXO, len(utxos))
copy(shuffledUTXOs, utxos)
rnd.Shuffle(len(shuffledUTXOs), func(i, j int) {
shuffledUTXOs[i], shuffledUTXOs[j] = shuffledUTXOs[j], shuffledUTXOs[i]
Expand All @@ -120,9 +120,9 @@ func subsetWithLeastOverFund(enough func(uint64, uint64) (bool, uint64), maxFund
if use {
included[i] = true
numIncluded++
nTotal += shuffledUTXOs[i].amount
totalSize += uint64(shuffledUTXOs[i].input.VBytes())
if e, _ := enough(totalSize, nTotal); e {
nTotal += shuffledUTXOs[i].Amount
totalSize += uint64(shuffledUTXOs[i].Input.VBytes())
if e, _ := enough(uint64(numIncluded), totalSize, nTotal); e {
if (nTotal < best || (nTotal == best && numIncluded < bestNumIncluded)) && nTotal <= maxFund {
best = nTotal
if bestIncluded == nil {
Expand All @@ -132,8 +132,8 @@ func subsetWithLeastOverFund(enough func(uint64, uint64) (bool, uint64), maxFund
bestNumIncluded = numIncluded
}
included[i] = false
nTotal -= shuffledUTXOs[i].amount
totalSize -= uint64(shuffledUTXOs[i].input.VBytes())
nTotal -= shuffledUTXOs[i].Amount
totalSize -= uint64(shuffledUTXOs[i].Input.VBytes())
numIncluded--
}
}
Expand All @@ -148,7 +148,7 @@ func subsetWithLeastOverFund(enough func(uint64, uint64) (bool, uint64), maxFund
return nil
}

set := make([]*compositeUTXO, 0, len(shuffledUTXOs))
set := make([]*CompositeUTXO, 0, len(shuffledUTXOs))
for i, inc := range bestIncluded {
if inc {
set = append(set, shuffledUTXOs[i])
Expand Down Expand Up @@ -176,19 +176,19 @@ func subsetWithLeastOverFund(enough func(uint64, uint64) (bool, uint64), maxFund
//
// If the provided UTXO set has less combined value than the requested amount a
// nil slice is returned.
func leastOverFund(enough func(inputsSize, sum uint64) (bool, uint64), utxos []*compositeUTXO) []*compositeUTXO {
func leastOverFund(enough EnoughFunc, utxos []*CompositeUTXO) []*CompositeUTXO {
return leastOverFundWithLimit(enough, math.MaxUint64, utxos)
}

// leastOverFundWithLimit is the same as leastOverFund, but with an additional
// maxFund parameter. The total value of the returned UTXOs will not exceed
// maxFund.
func leastOverFundWithLimit(enough func(inputsSize, sum uint64) (bool, uint64), maxFund uint64, utxos []*compositeUTXO) []*compositeUTXO {
func leastOverFundWithLimit(enough EnoughFunc, maxFund uint64, utxos []*CompositeUTXO) []*CompositeUTXO {
// Remove the UTXOs that are larger than maxFund
var smallEnoughUTXOs []*compositeUTXO
var smallEnoughUTXOs []*CompositeUTXO
idx := sort.Search(len(utxos), func(i int) bool {
utxo := utxos[i]
return utxo.amount > maxFund
return utxo.Amount > maxFund
})
if idx == len(utxos) {
smallEnoughUTXOs = utxos
Expand All @@ -200,24 +200,24 @@ func leastOverFundWithLimit(enough func(inputsSize, sum uint64) (bool, uint64),
// of smaller ones.
idx = sort.Search(len(smallEnoughUTXOs), func(i int) bool {
utxo := smallEnoughUTXOs[i]
e, _ := enough(uint64(utxo.input.VBytes()), utxo.amount)
e, _ := enough(1, uint64(utxo.Input.VBytes()), utxo.Amount)
return e
})
var small []*compositeUTXO
var single *compositeUTXO // only return this if smaller ones would use more
var small []*CompositeUTXO
var single *CompositeUTXO // only return this if smaller ones would use more
if idx == len(smallEnoughUTXOs) { // no one is enough
small = smallEnoughUTXOs
} else {
small = smallEnoughUTXOs[:idx]
single = smallEnoughUTXOs[idx]
}

var set []*compositeUTXO
smallSetTotalValue := sumUTXOs(small)
var set []*CompositeUTXO
smallSetTotalValue := SumUTXOs(small)
smallSetTotalSize := sumUTXOSize(small)
if e, _ := enough(smallSetTotalSize, smallSetTotalValue); !e {
if e, _ := enough(uint64(len(small)), smallSetTotalSize, smallSetTotalValue); !e {
if single != nil {
return []*compositeUTXO{single}
return []*CompositeUTXO{single}
} else {
return nil
}
Expand All @@ -226,18 +226,18 @@ func leastOverFundWithLimit(enough func(inputsSize, sum uint64) (bool, uint64),
}

// Return the small UTXO subset if it is less than the single big UTXO.
if single != nil && single.amount < sumUTXOs(set) {
return []*compositeUTXO{single}
if single != nil && single.Amount < SumUTXOs(set) {
return []*CompositeUTXO{single}
}

return set
}

// utxoSetDiff performs the setdiff(set,sub) of two UTXO sets. That is, any
// UTxOSetDiff performs the setdiff(set,sub) of two UTXO sets. That is, any
// UTXOs that are both sets are removed from the first. The comparison is done
// *by pointer*, with no regard to the values of the compositeUTXO elements.
func utxoSetDiff(set, sub []*compositeUTXO) []*compositeUTXO {
var availUTXOs []*compositeUTXO
// *by pointer*, with no regard to the values of the CompositeUTXO elements.
func UTxOSetDiff(set, sub []*CompositeUTXO) []*CompositeUTXO {
var availUTXOs []*CompositeUTXO
avail:
for _, utxo := range set {
for _, kept := range sub {
Expand Down
Loading