-
Notifications
You must be signed in to change notification settings - Fork 3
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
chore(submitter): remove dumpPrivKey #15
Conversation
- Upgrade bitcoind version - Use descriptors to import priv key
// on app level. Descriptor wallets do not allow dumping private keys. | ||
buff, _, err := h.m.ExecBitcoindCliCmd(h.t, []string{"createwallet", walletName, "false", "false", passphrase, "false", "false"}) | ||
// last arg is true which indicates we are using descriptor wallets they do not allow dumping private keys. | ||
buff, _, err := h.m.ExecBitcoindCliCmd(h.t, []string{"createwallet", walletName, "false", "false", passphrase, "false", "true"}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Legacy wallets were "false", true for descriptor wallets
@@ -386,44 +386,54 @@ func (rl *Relayer) buildTxWithData( | |||
rl.logger.Debugf("Building a BTC tx using %v with data %x", utxo.TxID.String(), data) | |||
tx := wire.NewMsgTx(wire.TxVersion) | |||
|
|||
outPoint := wire.NewOutPoint(utxo.TxID, utxo.Vout) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the utxo *types.UTXO
argument to the function is probably not needed now as all intput to the transaction as selected by rl.BTCWallet.FundRawTransaction
function.
Given that we probably need two versions of this function:
- first version for the first transaction, in which we allow wallet to chose inputs automatically
- second version for the second transaction, in which we are able to specifiy input manually to use the transaction chaining
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure how FundRawTransaction
would simplify things as we cannot control the inputs used by FundRawTransaction
. As such, for (1), how do we know the value of the output is sufficient to fund the second tx for chaining?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I understand our chaining mechanism correctly, want we want to do is:
- send first transaction with pretty low fee rate, lets call it
Tx1
- then send the second transaction (
Tx2
)with higher fee rate and with input that isTx1
change output (this is necessary to achieve the chaining)
Imo FundRawTransaction
can help here a lot and simplify stuff as:
- For the
Tx1
we can just create unsigned and unfunded transaction with one output, and send it toFundRawTransaction
, it will automatically choses inputs and add one change output which will have correct value to obey specified fee rate. - Then we can create
Tx2
with one input (change output fromTx1
) and one output and send it toFundRawTransaction
. Now based on specified fee rate, endpoint will attach or not other inputs and will attach one change output toTx2
. This way chaining will be preserved, and second tx will obey specified fee rate
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, I didn't realize in (2) we can inject one input from the change output of tx1. If the case, then it indeed improves a lot. Sounds good to me!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PR looks good, but what about dumpPrivKeyAndSignTx at the processCheckpoints
case
My bad, tested the wrong branch locally
e2etest/container/config.go
Outdated
@@ -10,7 +10,7 @@ type ImageConfig struct { | |||
//nolint:deadcode | |||
const ( | |||
dockerBitcoindRepository = "lncm/bitcoind" | |||
dockerBitcoindVersionTag = "v24.0.1" | |||
dockerBitcoindVersionTag = "v26.1" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🎉
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code changes looks good to me ^^
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Signing part lgtm! As per off-line discussion, my major concern is whether FundRawTransaction
can handle the chaining without introducing much complexity. Maybe this part can be improved in a separate pr to not block here
submitter/relayer/relayer.go
Outdated
// add unlocking script into the input of the tx | ||
tx, err = completeTxIn(tx, segwit, wif.PrivKey, utxo) | ||
|
||
signedTx, _, err := rl.BTCWallet.SignRawTransactionWithWallet(tx) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need to check the second output is true?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yep we should check this flag and retrun error if it is false
.
This flags indicate whether all inputs were signed, from caller perspective it means that if it is false
transaction cannot be sent to the BTC.
@@ -386,44 +386,54 @@ func (rl *Relayer) buildTxWithData( | |||
rl.logger.Debugf("Building a BTC tx using %v with data %x", utxo.TxID.String(), data) | |||
tx := wire.NewMsgTx(wire.TxVersion) | |||
|
|||
outPoint := wire.NewOutPoint(utxo.TxID, utxo.Vout) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure how FundRawTransaction
would simplify things as we cannot control the inputs used by FundRawTransaction
. As such, for (1), how do we know the value of the output is sufficient to fund the second tx for chaining?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We minor nits. Before merging lets wait for @gitferry approval as he is most familiar with this logic.
submitter/relayer/relayer.go
Outdated
rl.logger.Debugf("Got a change address %v", changeAddr.String()) | ||
changeScript, err := txscript.PayToAddrScript(changeAddr) | ||
feeRate := btcutil.Amount(rl.getFeeRate()).ToBTC() | ||
changePosition := 1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would make this a constant and the top of the file and use it to refer to change outputs wherever necessary, because now we have a lot magic numbers in the file e.g Transaction.TxOut[1]
submitter/relayer/relayer.go
Outdated
// add unlocking script into the input of the tx | ||
tx, err = completeTxIn(tx, segwit, wif.PrivKey, utxo) | ||
|
||
signedTx, _, err := rl.BTCWallet.SignRawTransactionWithWallet(tx) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yep we should check this flag and retrun error if it is false
.
This flags indicate whether all inputs were signed, from caller perspective it means that if it is false
transaction cannot be sent to the BTC.
submitter/relayer/relayer.go
Outdated
} | ||
change := utxo.Amount - txFee | ||
tx.AddTxOut(wire.NewTxOut(int64(change), changeScript)) | ||
change := changeAmount - txFee |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
imo this is not needed and you can use changeAmount
instead
submitter/relayer/utils.go
Outdated
return 0, err | ||
} | ||
|
||
btcTx, err := btcutil.NewTxFromBytes(txBytes.Bytes()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
here instead of first serializing transaction, you can use btcutil.NewTx(tx)
constructor, and remove serialization step
} | ||
|
||
// resendSecondTxOfCheckpointToBTC resends the second tx of the checkpoint with bumpedFee | ||
func (rl *Relayer) resendSecondTxOfCheckpointToBTC(tx2 *types.BtcTxInfo, bumpedFee btcutil.Amount) (*types.BtcTxInfo, error) { | ||
// set output value of the second tx to be the balance minus the bumped fee | ||
// if the bumped fee is higher than the balance, then set the bumped fee to | ||
// be equal to the balance to ensure the output value is not negative | ||
balance := tx2.Utxo.Amount | ||
balance := btcutil.Amount(tx2.Tx.TxOut[1].Value) | ||
|
||
if bumpedFee > balance { | ||
rl.logger.Debugf("the bumped fee %v Satoshis for the second tx is more than UTXO amount %v Satoshis", | ||
bumpedFee, balance) | ||
bumpedFee = balance |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is a bit debatable, as if we set bumpedFee = balance
and later have tx2.Tx.TxOut[1].Value = int64(balance - bumpedFee)
this means we will end up with output with value 0
that will be rejected by bitcoind as dust output.
This probably not for this pr, but some todo here for future fix would be good.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry for the delay. Some quick comments:
submitter/relayer/relayer.go
Outdated
// ChainTwoTxAndSend consumes one utxo and build two chaining txs: | ||
// the second tx consumes the output of the first tx |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// ChainTwoTxAndSend consumes one utxo and build two chaining txs: | |
// the second tx consumes the output of the first tx | |
// ChainTwoTxAndSend builds two chaining txs with the given data | |
// the second tx consumes the output of the first tx |
bumpedFee := newTx1Fee + newTx2Fee - ckptInfo.Tx1.Fee | ||
|
||
return bumpedFee.MulF64(float64(rl.config.ResubmitFeeMultiplier)) | ||
return ckptInfo.Tx2.Fee.MulF64(rl.config.ResubmitFeeMultiplier) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why we don't want to estimate the fee here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We've changed how we estimate fee, by using the fee value from the response of FundRawTransaction
. This produces a different value (a bit higher fee) than we used to, which means when we estimate the fee here it wouldn't be the same way as we did, and in local tests resulting in a lower calculated bumpedFee
needing a higher ResubmitFeeMultiplier
. So I see it either as estimating fee ourselves or using the response from FundRawTransaction
. Open to any other inputs, I might be missing something
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This makes sense. Thanks for the explanation!
// set output value of the second tx to be the balance minus the bumped fee | ||
// if the bumped fee is higher than the balance, then set the bumped fee to | ||
// be equal to the balance to ensure the output value is not negative |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems outdated
balance := tx2.Utxo.Amount | ||
balance := btcutil.Amount(tx2.Tx.TxOut[changePosition].Value) | ||
|
||
// todo: revise this as this means we will end up with output with value 0 that will be rejected by bitcoind as dust output. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we make it an issue for reminder?
submitter/relayer/relayer.go
Outdated
// buildTxWithData builds a tx with data inserted as OP_RETURN | ||
// note that OP_RETURN is set as the first output of the tx (index 0) | ||
// and the rest of the balance is sent to a new change address | ||
// as the second output with index 1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this doc string needs update
submitter/relayer/relayer.go
Outdated
tx.AddTxIn(txIn) | ||
if firstTx != nil { | ||
txID := firstTx.TxHash() | ||
outPoint := wire.NewOutPoint(&txID, 1) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we make 1
a self-explained constant?
return nil, err | ||
} | ||
|
||
change := changeAmount - txFee |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should we also check the change is higher than dust?
submitter/relayer/relayer.go
Outdated
return nil, err | ||
} | ||
|
||
change := changeAmount - txFee | ||
|
||
rl.logger.Debugf("Successfully composed a BTC tx with balance of input: %v, "+ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We probably need to remove the balance of input as we don't specify it anymore. And we need to make it a single line as otherwise the values are not well translated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great work! LGTM other than comments above
This pull request removes the usage of the dumpPrivKey RPC method from the submitter and end-to-end (E2E) tests. The dumpPrivKey method is specific to legacy wallets and is no longer supported in the latest versions of bitcoind. Eliminating its usage is a necessary step for upgrading to newer versions of bitcoind, as its deprecation would otherwise hinder the upgrade process.
Updates the version of bitcoind to v27.0
References issue.