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

Change calc update #33

Merged
merged 1 commit into from
Aug 11, 2021
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
43 changes: 10 additions & 33 deletions txchange.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,17 +82,11 @@ func (tx *Tx) change(s *bscript.Script, f []*Fee, newOutput bool) (uint64, bool,
tx.AddOutput(&Output{Satoshis: 0, LockingScript: s})
}

var preSignedFeeRequired uint64
if preSignedFeeRequired, err = tx.getPreSignedFeeRequired(f); err != nil {
var txFee uint64
if txFee, err = tx.getTransactionFees(f); err != nil {
return 0, false, err
}

var expectedUnlockingScriptFees uint64
if expectedUnlockingScriptFees, err = tx.getExpectedUnlockingScriptFees(f); err != nil {
return 0, false, err
}

available -= preSignedFeeRequired + expectedUnlockingScriptFees
available -= txFee

return available, true, nil
}
Expand All @@ -114,46 +108,29 @@ func (tx *Tx) canAddChange(available uint64, standardFees *Fee) bool {
return available >= changeOutputFee
}

func (tx *Tx) getPreSignedFeeRequired(f []*Fee) (uint64, error) {
func (tx *Tx) getTransactionFees(f []*Fee) (uint64, error) {

standardBytes, dataBytes := tx.getStandardAndDataBytes()

standardFee, err := ExtractStandardFee(f)
if err != nil {
return 0, err
}

for _, in := range tx.Inputs {
if !in.PreviousTxScript.IsP2PKH() {
return 0, errors.New("non-P2PKH input used in the tx - unsupported")
}
standardBytes += 107 // = 1 oppushdata + 70-71 sig + 1 sighash + 1 oppushdata + 33 public key
}
fr := standardBytes * standardFee.MiningFee.Satoshis / standardFee.MiningFee.Bytes

var dataFee *Fee
if dataFee, err = ExtractDataFee(f); err != nil {
return 0, err
}

fr += dataBytes * dataFee.MiningFee.Satoshis / dataFee.MiningFee.Bytes

return uint64(fr), nil
}

func (tx *Tx) getExpectedUnlockingScriptFees(f []*Fee) (uint64, error) {

standardFee, err := ExtractStandardFee(f)
if err != nil {
return 0, err
}

var expectedBytes int

for _, in := range tx.Inputs {
if !in.PreviousTxScript.IsP2PKH() {
return 0, errors.New("non-P2PKH input used in the tx - unsupported")
}
expectedBytes += 109 // = 1 oppushdata + 70-73 sig + 1 sighash + 1 oppushdata + 33 public key
}

return uint64(expectedBytes * standardFee.MiningFee.Satoshis / standardFee.MiningFee.Bytes), nil
}

func (tx *Tx) getStandardAndDataBytes() (standardBytes, dataBytes int) {
// Subtract the value of each output as well as keeping track of data Outputs
for _, out := range tx.Outputs {
Expand Down
8 changes: 4 additions & 4 deletions txchange_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -155,18 +155,18 @@ func TestTx_Change(t *testing.T) {
assert.NoError(t, err)

assert.Equal(t,
"0100000001760595866e99c1ce920197844740f5598b34763878696371d41b3a7c0a65b0b7000000006a473044022054ec562aefb1d5b4483906b0fa728a951b81944d8a82c2be1c6e7ea67e8c34b702200c2657c5d2a744d138bfb4204c579de20e984d680695823cba3fb7a0346b3c19412102c8803fdd437d902f08e3c2344cb33065c99d7c99982018ff9f7219c3dd352ff0ffffffff03f4010000000000001976a9147a1980655efbfec416b2b0c663a7b3ac0b6a25d288ac000000000000000011006a02686903686f770361726503796f757a010000000000001976a91484e50b300b009833b297dc671817c79b5459da1d88ac00000000",
"0100000001760595866e99c1ce920197844740f5598b34763878696371d41b3a7c0a65b0b7000000006a473044022034d403376154060bbbb4f828df545bfc23dd1174ef5ea626668ea31cec860b4702206a95c559bc612e7fc3746ce18456a6301ff16fd285798d4fbcfbd1c71e34047e412102c8803fdd437d902f08e3c2344cb33065c99d7c99982018ff9f7219c3dd352ff0ffffffff03f4010000000000001976a9147a1980655efbfec416b2b0c663a7b3ac0b6a25d288ac000000000000000011006a02686903686f770361726503796f757b010000000000001976a91484e50b300b009833b297dc671817c79b5459da1d88ac00000000",
tx.String(),
)

feePaid := tx.TotalInputSatoshis() - tx.TotalOutputSatoshis()
assert.Equal(t, uint64(122), feePaid)
assert.Equal(t, uint64(121), feePaid)

txSize := len(tx.Bytes())
assert.Equal(t, 251, txSize)

feeRate := float64(feePaid) / float64(txSize)
assert.Equal(t, 0.4860557768924303, feeRate)
assert.Equal(t, 0.4820717131474104, feeRate)
})

t.Run("spend entire utxo - basic - change address", func(t *testing.T) {
Expand Down Expand Up @@ -298,7 +298,7 @@ func TestTx_Change(t *testing.T) {
assert.ElementsMatch(t, []int{0, 1}, is)
assert.Equal(t, 2, len(is))

assert.Equal(t, "01000000028ee20a442cdbcc9f9f927d9c2c9370e611675ebc24c064e8e94508ec8eca889e000000006b483045022100fa52a44cd8010ba646a8df6bac6e5e8aa93f24439521c2ce1c8fe6550e73c1750220636e30d757702a6777d8310090962d4bac2b3fd634127856d51b184f5c702c8f4121034aaeabc056f33fd960d1e43fc8a0672723af02f275e54c31381af66a334634caffffffff42eaf7bdddc797a0beb97717ff8846f03c963fb5fe15a2b555b9cbd477b0254e000000006b483045022100c201fd55ef33525b3eb0557fac77408b8ec7f6ea5b00d08512df105172f992d60220753b21519a416dcbeaf1a501d9c36de2aea9c83c6d258320500371819d0758e14121034aaeabc056f33fd960d1e43fc8a0672723af02f275e54c31381af66a334634caffffffff01c62b0000000000001976a9147824dec00be2c45dad83c9b5e9f5d7ef05ba3cf988ac00000000", tx.String())
assert.Equal(t, "01000000028ee20a442cdbcc9f9f927d9c2c9370e611675ebc24c064e8e94508ec8eca889e000000006b483045022100f88298f5a380244dd5b91f70be99394f8e562d2a61976ca8cf2aaeb381ee6e6a0220069243fc951061b624cf96124263b857a65a53400846080b543e4a8c16e097ce4121034aaeabc056f33fd960d1e43fc8a0672723af02f275e54c31381af66a334634caffffffff42eaf7bdddc797a0beb97717ff8846f03c963fb5fe15a2b555b9cbd477b0254e000000006b483045022100afa7a986e6e0faf725a9779fe8e61fd19b5973544dc7707fd758cdd45912332a0220760fe07fc8610d867be5281f29778e3cd1a18a6eef74470d0f1a4ede95c848924121034aaeabc056f33fd960d1e43fc8a0672723af02f275e54c31381af66a334634caffffffff01c82b0000000000001976a9147824dec00be2c45dad83c9b5e9f5d7ef05ba3cf988ac00000000", tx.String())
})
}

Expand Down