Use CalculateTransactionOverallMass where needed

This commit is contained in:
Ori Newman 2024-09-11 16:40:23 +03:00
parent fda5557f59
commit 30fcd217ed
4 changed files with 81 additions and 7 deletions

View File

@ -25,7 +25,7 @@ func (s *server) BumpFee(_ context.Context, request *pb.BumpFeeRequest) (*pb.Bum
return nil, err
}
mass := s.txMassCalculator.CalculateTransactionMass(domainTx) // TODO: Does GetMempoolEntry already provide the mass?
mass := s.txMassCalculator.CalculateTransactionOverallMass(domainTx)
feeRate := float64(entry.Entry.Fee) / float64(mass)
newFeeRate, err := s.calculateFeeRate(request.FeeRate)
if err != nil {

View File

@ -275,7 +275,9 @@ func (s *server) estimateFeePerInput(feeRate float64) (uint64, error) {
return 0, err
}
mass, err := s.estimateMassAfterSignatures(mockTx)
// Here we use compute mass to avoid dividing by zero. This is ok since `s.estimateFeePerInput` is only used
// in the case of compound transactions that have a compute mass higher than its storage mass.
mass, err := s.estimateComputeMassAfterSignatures(mockTx)
if err != nil {
return 0, err
}
@ -287,7 +289,7 @@ func (s *server) estimateFeePerInput(feeRate float64) (uint64, error) {
return 0, err
}
massWithoutUTXO, err := s.estimateMassAfterSignatures(mockTxWithoutUTXO)
massWithoutUTXO, err := s.estimateComputeMassAfterSignatures(mockTxWithoutUTXO)
if err != nil {
return 0, err
}

View File

@ -105,7 +105,7 @@ func (s *server) mergeTransaction(
func (s *server) maybeSplitAndMergeTransaction(transaction *serialization.PartiallySignedTransaction, toAddress util.Address,
changeAddress util.Address, changeWalletAddress *walletAddress, feeRate float64) ([]*serialization.PartiallySignedTransaction, error) {
transactionMass, err := s.estimateMassAfterSignatures(transaction)
transactionMass, err := s.estimateComputeMassAfterSignatures(transaction)
if err != nil {
return nil, err
}
@ -222,7 +222,11 @@ func (s *server) estimateMassAfterSignatures(transaction *serialization.Partiall
return EstimateMassAfterSignatures(transaction, s.keysFile.ECDSA, s.keysFile.MinimumSignatures, s.txMassCalculator)
}
func EstimateMassAfterSignatures(transaction *serialization.PartiallySignedTransaction, ecdsa bool, minimumSignatures uint32, txMassCalculator *txmass.Calculator) (uint64, error) {
func (s *server) estimateComputeMassAfterSignatures(transaction *serialization.PartiallySignedTransaction) (uint64, error) {
return estimateComputeMassAfterSignatures(transaction, s.keysFile.ECDSA, s.keysFile.MinimumSignatures, s.txMassCalculator)
}
func createTransactionWithJunkFieldsForMassCalculation(transaction *serialization.PartiallySignedTransaction, ecdsa bool, minimumSignatures uint32, txMassCalculator *txmass.Calculator) (*externalapi.DomainTransaction, error) {
transaction = transaction.Clone()
var signatureSize uint64
if ecdsa {
@ -241,7 +245,11 @@ func EstimateMassAfterSignatures(transaction *serialization.PartiallySignedTrans
transaction.Tx.Inputs[i].SigOpCount = byte(len(input.PubKeySignaturePairs))
}
transactionWithSignatures, err := libkaspawallet.ExtractTransactionDeserialized(transaction, ecdsa)
return libkaspawallet.ExtractTransactionDeserialized(transaction, ecdsa)
}
func estimateComputeMassAfterSignatures(transaction *serialization.PartiallySignedTransaction, ecdsa bool, minimumSignatures uint32, txMassCalculator *txmass.Calculator) (uint64, error) {
transactionWithSignatures, err := createTransactionWithJunkFieldsForMassCalculation(transaction, ecdsa, minimumSignatures, txMassCalculator)
if err != nil {
return 0, err
}
@ -249,6 +257,15 @@ func EstimateMassAfterSignatures(transaction *serialization.PartiallySignedTrans
return txMassCalculator.CalculateTransactionMass(transactionWithSignatures), nil
}
func EstimateMassAfterSignatures(transaction *serialization.PartiallySignedTransaction, ecdsa bool, minimumSignatures uint32, txMassCalculator *txmass.Calculator) (uint64, error) {
transactionWithSignatures, err := createTransactionWithJunkFieldsForMassCalculation(transaction, ecdsa, minimumSignatures, txMassCalculator)
if err != nil {
return 0, err
}
return txMassCalculator.CalculateTransactionOverallMass(transactionWithSignatures), nil
}
func (s *server) moreUTXOsForMergeTransaction(alreadySelectedUTXOs []*libkaspawallet.UTXO, requiredAmount uint64, feeRate float64) (
additionalUTXOs []*libkaspawallet.UTXO, totalValueAdded uint64, err error) {

View File

@ -20,11 +20,62 @@ import (
"github.com/kaspanet/kaspad/domain/consensus/utils/testutils"
)
func TestEstimateComputeMassAfterSignatures(t *testing.T) {
testutils.ForAllNets(t, true, func(t *testing.T, consensusConfig *consensus.Config) {
unsignedTransaction, mnemonics, params, teardown := testEstimateMassIncreaseForSignaturesSetUp(t, consensusConfig)
defer teardown(false)
serverInstance := &server{
params: params,
keysFile: &keys.File{MinimumSignatures: 2},
shutdown: make(chan struct{}),
addressSet: make(walletAddressSet),
txMassCalculator: txmass.NewCalculator(params.MassPerTxByte, params.MassPerScriptPubKeyByte, params.MassPerSigOp),
}
estimatedMassAfterSignatures, err := serverInstance.estimateComputeMassAfterSignatures(unsignedTransaction)
if err != nil {
t.Fatalf("Error from estimateMassAfterSignatures: %s", err)
}
unsignedTransactionBytes, err := serialization.SerializePartiallySignedTransaction(unsignedTransaction)
if err != nil {
t.Fatalf("Error deserializing unsignedTransaction: %s", err)
}
signedTxStep1Bytes, err := libkaspawallet.Sign(params, mnemonics[:1], unsignedTransactionBytes, false)
if err != nil {
t.Fatalf("Sign: %+v", err)
}
signedTxStep2Bytes, err := libkaspawallet.Sign(params, mnemonics[1:2], signedTxStep1Bytes, false)
if err != nil {
t.Fatalf("Sign: %+v", err)
}
extractedSignedTx, err := libkaspawallet.ExtractTransaction(signedTxStep2Bytes, false)
if err != nil {
t.Fatalf("ExtractTransaction: %+v", err)
}
actualMassAfterSignatures := serverInstance.txMassCalculator.CalculateTransactionMass(extractedSignedTx)
if estimatedMassAfterSignatures != actualMassAfterSignatures {
t.Errorf("Estimated mass after signatures: %d but actually got %d",
estimatedMassAfterSignatures, actualMassAfterSignatures)
}
})
}
func TestEstimateMassAfterSignatures(t *testing.T) {
testutils.ForAllNets(t, true, func(t *testing.T, consensusConfig *consensus.Config) {
unsignedTransaction, mnemonics, params, teardown := testEstimateMassIncreaseForSignaturesSetUp(t, consensusConfig)
defer teardown(false)
for i := range unsignedTransaction.Tx.Inputs {
unsignedTransaction.Tx.Inputs[i].UTXOEntry = utxo.NewUTXOEntry(1, &externalapi.ScriptPublicKey{}, false, 0)
}
serverInstance := &server{
params: params,
keysFile: &keys.File{MinimumSignatures: 2},
@ -58,7 +109,11 @@ func TestEstimateMassAfterSignatures(t *testing.T) {
t.Fatalf("ExtractTransaction: %+v", err)
}
actualMassAfterSignatures := serverInstance.txMassCalculator.CalculateTransactionMass(extractedSignedTx)
for i := range extractedSignedTx.Inputs {
extractedSignedTx.Inputs[i].UTXOEntry = utxo.NewUTXOEntry(1, &externalapi.ScriptPublicKey{}, false, 0)
}
actualMassAfterSignatures := serverInstance.txMassCalculator.CalculateTransactionOverallMass(extractedSignedTx)
if estimatedMassAfterSignatures != actualMassAfterSignatures {
t.Errorf("Estimated mass after signatures: %d but actually got %d",