Skip to content

Commit

Permalink
Use createSplitTransaction to calculate the upper bound of mass for s…
Browse files Browse the repository at this point in the history
…plit transactions
  • Loading branch information
svarogg committed Mar 27, 2022
1 parent 92d9a73 commit 88857c8
Showing 1 changed file with 23 additions and 8 deletions.
31 changes: 23 additions & 8 deletions cmd/kaspawallet/daemon/server/split_transaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,10 @@ func (s *server) maybeSplitTransaction(transaction *serialization.PartiallySigne
return []*serialization.PartiallySignedTransaction{transaction}, nil
}

splitCount, inputCountPerSplit := s.splitAndInputPerSplitCounts(transaction, transactionMass)
splitCount, inputCountPerSplit, err := s.splitAndInputPerSplitCounts(transaction, transactionMass, changeAddress)
if err != nil {
return nil, err
}

splitTransactions := make([]*serialization.PartiallySignedTransaction, splitCount)
for i := 0; i < splitCount; i++ {
Expand All @@ -142,30 +145,42 @@ func (s *server) maybeSplitTransaction(transaction *serialization.PartiallySigne
}

// splitAndInputPerSplitCounts calculates the number of splits to create, and the number of inputs to assign per split.
func (s *server) splitAndInputPerSplitCounts(transaction *serialization.PartiallySignedTransaction, transactionMass uint64) (
splitCount, inputsPerSplitCount int) {
func (s *server) splitAndInputPerSplitCounts(transaction *serialization.PartiallySignedTransaction, transactionMass uint64,
changeAddress util.Address) (splitCount, inputsPerSplitCount int, err error) {

// Create a dummy transaction which is a clone of the original transaction, but without inputs,
// to calculate how much mass do all the inputs have
transactionWithoutInputs := transaction.Tx.Clone()
transactionWithoutInputs.Inputs = []*externalapi.DomainTransactionInput{}
massWithoutInputs := s.txMassCalculator.CalculateTransactionMass(transactionWithoutInputs)

massForInputs := transactionMass - massWithoutInputs
massOfAllInputs := transactionMass - massWithoutInputs

// Since the transaction was generated by kaspawallet, we assume all inputs have the same number of signatures, and
// thus - the same mass.
inputCount := len(transaction.Tx.Inputs)
massPerInput := massForInputs / uint64(inputCount)
if massForInputs%uint64(inputCount) > 0 {
massPerInput := massOfAllInputs / uint64(inputCount)
if massOfAllInputs%uint64(inputCount) > 0 {
massPerInput++
}

inputsPerSplitCount = int((mempool.MaximumStandardTransactionMass - massWithoutInputs) / massPerInput)
// Create another dummy transaction, this time one similar to the split transactions we wish to generate,
// but with 0 inputs, to calculate how much mass for inputs do we have available in the split transactions
splitTransactionWithoutInputs, err := s.createSplitTransaction(transaction, changeAddress, 0, 0)
if err != nil {
return 0, 0, err
}
massForEverythingExceptInputsInSplitTransaction :=
s.txMassCalculator.CalculateTransactionMass(splitTransactionWithoutInputs.Tx)
massForInputsInSplitTransaction := mempool.MaximumStandardTransactionMass - massForEverythingExceptInputsInSplitTransaction

inputsPerSplitCount = int(massForInputsInSplitTransaction / massPerInput)
splitCount = inputCount / inputsPerSplitCount
if inputCount%inputsPerSplitCount > 0 {
splitCount++
}

return splitCount, inputsPerSplitCount
return splitCount, inputsPerSplitCount, nil
}

func (s *server) createSplitTransaction(transaction *serialization.PartiallySignedTransaction,
Expand Down

0 comments on commit 88857c8

Please sign in to comment.