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

Add flag for enabling RB #644

Merged
merged 1 commit into from
Feb 5, 2024
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
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,8 @@ class MainViewModel : ViewModel(), BitcoinKit.Listener {
amount!!,
feeRate = feePriority.feeRate,
sortType = TransactionDataSortType.Shuffle,
pluginData = getPluginData()
pluginData = getPluginData(),
rbfEnabled = true
)

amountLiveData.value = null
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,9 +90,10 @@ abstract class AbstractKit {
feeRate: Int,
sortType: TransactionDataSortType,
unspentOutputs: List<UnspentOutputInfo>? = null,
pluginData: Map<Byte, IPluginData> = mapOf()
pluginData: Map<Byte, IPluginData> = mapOf(),
rbfEnabled: Boolean,
): FullTransaction {
return bitcoinCore.send(address, value, senderPay, feeRate, sortType, unspentOutputs, pluginData)
return bitcoinCore.send(address, value, senderPay, feeRate, sortType, unspentOutputs, pluginData, rbfEnabled)
}

fun send(
Expand All @@ -101,9 +102,10 @@ abstract class AbstractKit {
senderPay: Boolean = true,
feeRate: Int,
sortType: TransactionDataSortType,
pluginData: Map<Byte, IPluginData> = mapOf()
pluginData: Map<Byte, IPluginData> = mapOf(),
rbfEnabled: Boolean,
): FullTransaction {
return bitcoinCore.send(address, value, senderPay, feeRate, sortType, null, pluginData)
return bitcoinCore.send(address, value, senderPay, feeRate, sortType, null, pluginData, rbfEnabled)
}

fun send(
Expand All @@ -114,8 +116,9 @@ abstract class AbstractKit {
feeRate: Int,
sortType: TransactionDataSortType,
unspentOutputs: List<UnspentOutputInfo>? = null,
rbfEnabled: Boolean,
): FullTransaction {
return bitcoinCore.send(hash, scriptType, value, senderPay, feeRate, sortType, unspentOutputs)
return bitcoinCore.send(hash, scriptType, value, senderPay, feeRate, sortType, unspentOutputs, rbfEnabled)
}

fun send(
Expand All @@ -125,12 +128,13 @@ abstract class AbstractKit {
senderPay: Boolean = true,
feeRate: Int,
sortType: TransactionDataSortType,
rbfEnabled: Boolean,
): FullTransaction {
return bitcoinCore.send(hash, scriptType, value, senderPay, feeRate, sortType, null)
return bitcoinCore.send(hash, scriptType, value, senderPay, feeRate, sortType, null, rbfEnabled)
}

fun redeem(unspentOutput: UnspentOutput, address: String, feeRate: Int, sortType: TransactionDataSortType): FullTransaction {
return bitcoinCore.redeem(unspentOutput, address, feeRate, sortType)
fun redeem(unspentOutput: UnspentOutput, address: String, feeRate: Int, sortType: TransactionDataSortType, rbfEnabled: Boolean): FullTransaction {
return bitcoinCore.redeem(unspentOutput, address, feeRate, sortType, rbfEnabled)
}

fun receiveAddress(): String {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,8 @@ class BitcoinCore(
feeRate: Int,
sortType: TransactionDataSortType,
unspentOutputs: List<UnspentOutputInfo>?,
pluginData: Map<Byte, IPluginData>
pluginData: Map<Byte, IPluginData>,
rbfEnabled: Boolean
): FullTransaction {
val outputs = unspentOutputs?.mapNotNull {
unspentOutputSelector.all.firstOrNull { unspentOutput ->
Expand All @@ -221,7 +222,8 @@ class BitcoinCore(
senderPay = senderPay,
sortType = sortType,
unspentOutputs = outputs,
pluginData = pluginData
pluginData = pluginData,
rbfEnabled = rbfEnabled
) ?: throw CoreError.ReadOnlyCore
}

Expand All @@ -233,6 +235,7 @@ class BitcoinCore(
feeRate: Int,
sortType: TransactionDataSortType,
unspentOutputs: List<UnspentOutputInfo>?,
rbfEnabled: Boolean
): FullTransaction {
val address = addressConverter.convert(hash, scriptType)
val outputs = unspentOutputs?.mapNotNull {
Expand All @@ -247,12 +250,13 @@ class BitcoinCore(
senderPay = senderPay,
sortType = sortType,
unspentOutputs = outputs,
pluginData = mapOf()
pluginData = mapOf(),
rbfEnabled = rbfEnabled
) ?: throw CoreError.ReadOnlyCore
}

fun redeem(unspentOutput: UnspentOutput, address: String, feeRate: Int, sortType: TransactionDataSortType): FullTransaction {
return transactionCreator?.create(unspentOutput, address, feeRate, sortType) ?: throw CoreError.ReadOnlyCore
fun redeem(unspentOutput: UnspentOutput, address: String, feeRate: Int, sortType: TransactionDataSortType, rbfEnabled: Boolean): FullTransaction {
return transactionCreator?.create(unspentOutput, address, feeRate, sortType, rbfEnabled) ?: throw CoreError.ReadOnlyCore
}

fun receiveAddress(): String {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ class TransactionCreator(
senderPay: Boolean,
sortType: TransactionDataSortType,
unspentOutputs: List<UnspentOutput>?,
pluginData: Map<Byte, IPluginData>
pluginData: Map<Byte, IPluginData>,
rbfEnabled: Boolean
): FullTransaction {
return create {
builder.buildTransaction(
Expand All @@ -32,7 +33,8 @@ class TransactionCreator(
senderPay = senderPay,
sortType = sortType,
unspentOutputs = unspentOutputs,
pluginData = pluginData
pluginData = pluginData,
rbfEnabled = rbfEnabled
)
}
}
Expand All @@ -42,10 +44,11 @@ class TransactionCreator(
unspentOutput: UnspentOutput,
toAddress: String,
feeRate: Int,
sortType: TransactionDataSortType
sortType: TransactionDataSortType,
rbfEnabled: Boolean
): FullTransaction {
return create {
builder.buildTransaction(unspentOutput, toAddress, feeRate, sortType)
builder.buildTransaction(unspentOutput, toAddress, feeRate, sortType, rbfEnabled)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ class TransactionFeeCalculator(
feeRate = feeRate,
senderPay = senderPay,
unspentOutputs = unspentOutputs,
sortType = TransactionDataSortType.None
sortType = TransactionDataSortType.None,
rbfEnabled = false
)

val inputsTotalValue = mutableTransaction.inputsToSign.sumOf { it.previousOutput.value }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ class InputSetter(
fun setInputs(
mutableTransaction: MutableTransaction,
unspentOutput: UnspentOutput,
feeRate: Int
feeRate: Int,
rbfEnabled: Boolean
) {
if (unspentOutput.output.scriptType != ScriptType.P2SH) {
throw TransactionBuilder.BuilderException.NotSupportedScriptType()
Expand All @@ -49,7 +50,7 @@ class InputSetter(
if (value < fee) {
throw TransactionBuilder.BuilderException.FeeMoreThanValue()
}
mutableTransaction.addInput(inputToSign(unspentOutput))
mutableTransaction.addInput(inputToSign(unspentOutput, rbfEnabled))
mutableTransaction.recipientValue = value - fee
}

Expand All @@ -59,7 +60,8 @@ class InputSetter(
feeRate: Int,
senderPay: Boolean,
unspentOutputs: List<UnspentOutput>?,
sortType: TransactionDataSortType
sortType: TransactionDataSortType,
rbfEnabled: Boolean
): OutputInfo {
val unspentOutputInfo: SelectedUnspentOutputInfo
if (unspentOutputs != null) {
Expand Down Expand Up @@ -95,7 +97,7 @@ class InputSetter(
transactionDataSorterFactory.sorter(sortType).sortUnspents(unspentOutputInfo.outputs)

for (unspentOutput in sortedUnspentOutputs) {
mutableTransaction.addInput(inputToSign(unspentOutput))
mutableTransaction.addInput(inputToSign(unspentOutput, rbfEnabled))
}

mutableTransaction.recipientValue = unspentOutputInfo.recipientValue
Expand All @@ -118,10 +120,14 @@ class InputSetter(
)
}

private fun inputToSign(unspentOutput: UnspentOutput): InputToSign {
private fun inputToSign(unspentOutput: UnspentOutput, rbfEnabled: Boolean): InputToSign {
val previousOutput = unspentOutput.output
val transactionInput =
TransactionInput(previousOutput.transactionHash, previousOutput.index.toLong())
val sequence = if (rbfEnabled) {
0x00
} else {
0xfffffffe
}
val transactionInput = TransactionInput(previousOutput.transactionHash, previousOutput.index.toLong(), sequence = sequence)

return InputToSign(transactionInput, previousOutput, unspentOutput.publicKey)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,27 @@ import io.horizontalsystems.bitcoincore.storage.FullTransaction
import io.horizontalsystems.bitcoincore.storage.UnspentOutput

class TransactionBuilder(
private val recipientSetter: IRecipientSetter,
private val outputSetter: OutputSetter,
private val inputSetter: InputSetter,
private val signer: TransactionSigner,
private val lockTimeSetter: LockTimeSetter
private val recipientSetter: IRecipientSetter,
private val outputSetter: OutputSetter,
private val inputSetter: InputSetter,
private val signer: TransactionSigner,
private val lockTimeSetter: LockTimeSetter
) {

fun buildTransaction(toAddress: String, value: Long, feeRate: Int, senderPay: Boolean, sortType: TransactionDataSortType, unspentOutputs: List<UnspentOutput>?, pluginData: Map<Byte, IPluginData>): FullTransaction {
fun buildTransaction(
toAddress: String,
value: Long,
feeRate: Int,
senderPay: Boolean,
sortType: TransactionDataSortType,
unspentOutputs: List<UnspentOutput>?,
pluginData: Map<Byte, IPluginData>,
rbfEnabled: Boolean
): FullTransaction {
val mutableTransaction = MutableTransaction()

recipientSetter.setRecipient(mutableTransaction, toAddress, value, pluginData, false)
inputSetter.setInputs(mutableTransaction, feeRate, senderPay, unspentOutputs, sortType)
inputSetter.setInputs(mutableTransaction, feeRate, senderPay, unspentOutputs, sortType, rbfEnabled)
lockTimeSetter.setLockTime(mutableTransaction)

outputSetter.setOutputs(mutableTransaction, sortType)
Expand All @@ -27,11 +36,17 @@ class TransactionBuilder(
return mutableTransaction.build()
}

fun buildTransaction(unspentOutput: UnspentOutput, toAddress: String, feeRate: Int, sortType: TransactionDataSortType): FullTransaction {
fun buildTransaction(
unspentOutput: UnspentOutput,
toAddress: String,
feeRate: Int,
sortType: TransactionDataSortType,
rbfEnabled: Boolean
): FullTransaction {
val mutableTransaction = MutableTransaction(false)

recipientSetter.setRecipient(mutableTransaction, toAddress, unspentOutput.output.value, mapOf(), false)
inputSetter.setInputs(mutableTransaction, unspentOutput, feeRate)
inputSetter.setInputs(mutableTransaction, unspentOutput, feeRate, rbfEnabled)
lockTimeSetter.setLockTime(mutableTransaction)

outputSetter.setOutputs(mutableTransaction, sortType)
Expand Down
Loading