Skip to content

Commit

Permalink
adjusting tx input sig size to a max of 71 bytes for a total of 107 p…
Browse files Browse the repository at this point in the history
…er input. Adjusting fee calcs for bytes and std to do the calc in one place to avoid rounding issues
  • Loading branch information
theflyingcodr committed Aug 10, 2021
1 parent 97fd3b2 commit 5b1443a
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 37 deletions.
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

0 comments on commit 5b1443a

Please sign in to comment.