mirror of
https://github.com/bitcoin-s/bitcoin-s.git
synced 2024-11-19 18:02:54 +01:00
Refactored to allow support and disabling of RBF (#1588)
Co-authored-by: Ben Carman <benthecarman@live.com>
This commit is contained in:
parent
46e26e6be1
commit
35822f4f33
@ -1,7 +1,9 @@
|
||||
package org.bitcoins.core.policy
|
||||
|
||||
import org.bitcoins.core.currency.{CurrencyUnit, CurrencyUnits, Satoshis}
|
||||
import org.bitcoins.core.number.UInt32
|
||||
import org.bitcoins.core.script.flag._
|
||||
import org.bitcoins.core.wallet.fee.{FeeUnit, SatoshisPerVirtualByte}
|
||||
|
||||
/**
|
||||
* Created by chris on 4/6/16.
|
||||
@ -63,10 +65,13 @@ sealed abstract class Policy {
|
||||
/** A default fee to use per byte on the bitcoin network */
|
||||
def defaultFee: CurrencyUnit = Satoshis(50)
|
||||
|
||||
/** A default fee to use per byte on the bitcoin network */
|
||||
def defaultFeeRate: FeeUnit = SatoshisPerVirtualByte(defaultFee)
|
||||
|
||||
/** Max fee for a transaction is set to 10 mBTC right now */
|
||||
def maxFee: CurrencyUnit = Satoshis(10) * CurrencyUnits.oneMBTC
|
||||
|
||||
def isRBFEnabled: Boolean = true
|
||||
def sequence: UInt32 = UInt32.zero
|
||||
}
|
||||
|
||||
object Policy extends Policy
|
||||
|
@ -1,6 +1,7 @@
|
||||
package org.bitcoins.core.protocol.transaction
|
||||
|
||||
import org.bitcoins.core.number.UInt32
|
||||
import org.bitcoins.core.policy.Policy
|
||||
import org.bitcoins.core.protocol.script.{
|
||||
CLTVScriptPubKey,
|
||||
CSVScriptPubKey,
|
||||
@ -55,7 +56,7 @@ object InputUtil {
|
||||
*/
|
||||
def calcSequenceForInputs(
|
||||
utxos: Seq[InputSigningInfo[InputInfo]],
|
||||
isRBFEnabled: Boolean): Seq[TransactionInput] = {
|
||||
defaultSequence: UInt32 = Policy.sequence): Seq[TransactionInput] = {
|
||||
@tailrec
|
||||
def loop(
|
||||
remaining: Seq[InputSigningInfo[InputInfo]],
|
||||
@ -75,13 +76,10 @@ object InputUtil {
|
||||
loop(newRemaining, input +: accum)
|
||||
case p2pkWithTimeout: P2PKWithTimeoutInputInfo =>
|
||||
if (p2pkWithTimeout.isBeforeTimeout) {
|
||||
val sequence =
|
||||
if (isRBFEnabled) UInt32.zero
|
||||
else TransactionConstants.sequence
|
||||
val input =
|
||||
TransactionInput(spendingInfo.outPoint,
|
||||
EmptyScriptSignature,
|
||||
sequence)
|
||||
defaultSequence)
|
||||
loop(newRemaining, input +: accum)
|
||||
} else {
|
||||
val sequence = solveSequenceForCSV(
|
||||
@ -106,15 +104,11 @@ object InputUtil {
|
||||
case _: P2WPKHV0InputInfo | _: UnassignedSegwitNativeInputInfo |
|
||||
_: P2PKInputInfo | _: P2PKHInputInfo |
|
||||
_: MultiSignatureInputInfo | _: EmptyInputInfo =>
|
||||
//none of these script types affect the sequence number of a tx
|
||||
//the sequence only needs to be adjustd if we have replace by fee (RBF) enabled
|
||||
//see BIP125 for more information
|
||||
val sequence =
|
||||
if (isRBFEnabled) UInt32.zero else TransactionConstants.sequence
|
||||
//none of these script types affect the sequence number of a tx so the defaultSequence is used
|
||||
val input =
|
||||
TransactionInput(spendingInfo.outPoint,
|
||||
EmptyScriptSignature,
|
||||
sequence)
|
||||
defaultSequence)
|
||||
loop(newRemaining, input +: accum)
|
||||
}
|
||||
}
|
||||
|
@ -11,6 +11,7 @@ trait TransactionConstants {
|
||||
lazy val validLockVersion = Int32.two
|
||||
lazy val lockTime = UInt32.zero
|
||||
lazy val sequence = UInt32.max
|
||||
lazy val disableRBFSequence = sequence - UInt32.one
|
||||
|
||||
/**
|
||||
* If bit (1 << 31) of the sequence number is set,
|
||||
|
@ -251,7 +251,7 @@ object StandardNonInteractiveFinalizer {
|
||||
feeRate: FeeUnit,
|
||||
changeSPK: ScriptPubKey): RawTxBuilderWithFinalizer[
|
||||
StandardNonInteractiveFinalizer] = {
|
||||
val inputs = InputUtil.calcSequenceForInputs(utxos, Policy.isRBFEnabled)
|
||||
val inputs = InputUtil.calcSequenceForInputs(utxos)
|
||||
val lockTime = TxUtil.calcLockTime(utxos).get
|
||||
val builder = RawTxBuilder().setLockTime(lockTime) ++= outputs ++= inputs
|
||||
val finalizer = StandardNonInteractiveFinalizer(
|
||||
|
@ -2,7 +2,6 @@ package org.bitcoins.testkit.core.gen
|
||||
|
||||
import org.bitcoins.core.currency.CurrencyUnit
|
||||
import org.bitcoins.core.number.{Int32, UInt32}
|
||||
import org.bitcoins.core.policy.Policy
|
||||
import org.bitcoins.core.protocol.script.ScriptPubKey
|
||||
import org.bitcoins.core.protocol.transaction.{
|
||||
BaseTransaction,
|
||||
@ -200,7 +199,7 @@ object PSBTGenerators {
|
||||
(PSBT, FinalizedTxWithSigningInfo, FeeUnit)] = {
|
||||
val lockTime = TxUtil.calcLockTime(creditingTxsInfo).get
|
||||
val inputs =
|
||||
InputUtil.calcSequenceForInputs(creditingTxsInfo, Policy.isRBFEnabled)
|
||||
InputUtil.calcSequenceForInputs(creditingTxsInfo)
|
||||
|
||||
val builder = RawTxBuilder().setLockTime(lockTime) ++= destinations ++= inputs
|
||||
val finalizer = StandardNonInteractiveFinalizer(
|
||||
|
@ -2,7 +2,6 @@ package org.bitcoins.wallet.internal
|
||||
|
||||
import org.bitcoins.commons.jsonmodels.wallet.CoinSelectionAlgo
|
||||
import org.bitcoins.core.consensus.Consensus
|
||||
import org.bitcoins.core.policy.Policy
|
||||
import org.bitcoins.core.protocol.transaction.{
|
||||
EmptyTransactionOutPoint,
|
||||
InputUtil,
|
||||
@ -106,6 +105,8 @@ trait FundTransactionHandling extends WalletLogger { self: WalletApi =>
|
||||
val addrInfosWithUtxoF: Future[Vector[(SpendingInfoDb, AddressInfo)]] =
|
||||
for {
|
||||
selectedUtxos <- selectedUtxosF
|
||||
_ = selectedUtxosF.failed.foreach(err =>
|
||||
logger.error("Error selecting utxos to fund transaction ", err))
|
||||
addrInfoOptF = selectedUtxos.map { utxo =>
|
||||
val addrInfoOptF = getAddressInfo(utxo)
|
||||
//.get should be safe here because of foreign key at the database level
|
||||
@ -146,7 +147,7 @@ trait FundTransactionHandling extends WalletLogger { self: WalletApi =>
|
||||
}
|
||||
|
||||
val inputs =
|
||||
InputUtil.calcSequenceForInputs(utxoSpendingInfos, Policy.isRBFEnabled)
|
||||
InputUtil.calcSequenceForInputs(utxoSpendingInfos)
|
||||
|
||||
val lockTime = TxUtil.calcLockTime(utxoSpendingInfos).get
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user