Refactored to allow support and disabling of RBF (#1588)

Co-authored-by: Ben Carman <benthecarman@live.com>
This commit is contained in:
Nadav Kohen 2020-06-18 13:23:14 -05:00 committed by GitHub
parent 46e26e6be1
commit 35822f4f33
6 changed files with 17 additions and 17 deletions

View File

@ -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

View File

@ -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)
}
}

View File

@ -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,

View File

@ -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(

View File

@ -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(

View File

@ -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