Browse Source

add test cases, move marker, flag to witness

master
Adam Gibson 3 years ago
parent
commit
4921d01b92
No known key found for this signature in database
GPG Key ID: 141001A1AF77F20B
  1. 4
      jmbitcoin/jmbitcoin/secp256k1_transaction.py
  2. 31
      jmbitcoin/test/test_tx_signing.py
  3. 4
      jmclient/jmclient/wallet.py
  4. 6
      jmclient/test/test_taker.py

4
jmbitcoin/jmbitcoin/secp256k1_transaction.py

@ -168,8 +168,8 @@ def estimate_tx_size(ins, outs):
wsize = 0 wsize = 0
tx_is_segwit = there_is_one_segwit_input(ins) tx_is_segwit = there_is_one_segwit_input(ins)
if tx_is_segwit: if tx_is_segwit:
# flag and marker bytes # flag and marker bytes are included in witness
nwsize += 2 wsize += 2
for i in ins: for i in ins:
if i not in inmults: if i not in inmults:

31
jmbitcoin/test/test_tx_signing.py

@ -3,25 +3,46 @@ import pytest
import hashlib import hashlib
from jmbase import bintohex from jmbase import bintohex
import jmbitcoin as btc import jmbitcoin as btc
from math import ceil
# Cases copied from: # Case of spending into a FB, one p2wpkh input, one FB output, one p2wpkh output:
#
# "020000000001019b3a5c6ec9712bd6b1aa1e07ed12a677eb21215430fb84a689664fb0d4fa175a0000000000feffffff0290099c0a000000001600144d32ca4673822334531a2941bb85bff075c384d180b14f0100000000220020dae515a98f31542dd6b21bb0b0e31fccc4ebcdc9ba3e225798bc981ccbb8a21d024830450221009bc5fb8d077b32304c02a886926a68110bc7c5195a92b55977bd4affd23ab2d50220774e88828cf80cba4bb2e277a69a7c693c3566b5b72a0c0cf25cba89df0646d30121036d1baed4008f0d7f03ac41bbdbe46e02eeef6f040f7bdbc41adac30c2cf8831886020000"
#
# case of spending from a FB, single input, to 2 p2wpkh outputs
# "020000000001013499e10a8035a3cb928f5a894b2a3feed7d46ab579f0a2211a17ed1df0e2d9660100000000feffffff02405dc6000000000016001486551870825ef64d7fda89cc2a6fda497ab71a02954d8900000000001600147c24b9a3ddf5eb26142fb3f05a3746a0a582f81a0247304402206ca2049154939b083a5eb22713d3cb78f6673f43828fa4a7ef0f03275584da6c0220770fe7d50ba5e0a5f8039f28c5deaaf1e8b2030008bf51cc8721cf088eab5586012a0480c22e61b175210376e5964ee2c328e85b88a50f02953b1cddb1490825140331a3948023cc19946bac81c22e61"
#
# case of spending from an FB plus one more p2wpkh input, spending to a p2sh output and a p2wpkh output
# "02000000000102117efb788cee9644d5493fc9d1a120598f4f5200bb6909c0ebdac66cf88da80a0100000000feffffffb0f3ce583987d08080684e2c75d2d6871cb2d30f610327671440d7121c14b7ab0000000000feffffff0240a5ae020000000017a914c579342c2c4c9220205e2cdc285617040c924a0a8797027a00000000001600146fad63e6420ec3eb423a105b05c6df6cc8dab92902473044022040f1db3289d8c6e0dd94c0f55254f10512486094e36fd92f4423abc95320418902206718670b3f332d84cf8294ad389155594ebe125988f2f535c58ff3b077471ce9012102f9306fdc84a366f21fed44fbdd9149a046829f26fb52e7a316b19b536c18d2df0247304402207d0fde11ce32f48107ac246a01efad1c22b9466cd9ff4d5683030790bcb34ce5022020014fcf1b1b0606db5ef363568f10476524f7102644691a8a435faa17cbbe88012a04804f5661b17521037a9502304b2810706adef15b884ac7ca0c48c2e5d03cf93934487b44feb7c276ac814f5661"
#
# case of spending from one FB input to one FB output
#
# "0200000000010150c8e3786d357cbe61d8e27de7439e1b32d75d0a0ad596c5ff2863134cbd3ead0100000000feffffff01db84f701000000002200208b8ed0bc565e419dd956c3841b7bb25f7c197e2699002bac58a68f47206e1f340247304402202a639209aa9a2883ad75210edce2165260167435f56cede83e8c74095944f355022050fde591f1fefb615a072a797ace3c332c678e0f9161e58d79efa1705f9ab17c012a04002e7f61b1752103d4d747d0dca80c129c017ec1cdc658945013e04ff3d6946f15ccc9df52c323f0ac012e7f61"
#
# Virtual sizes can be calculated from bitcointx.core.CTransaction.deserialize(unhexlify(txhex)).get_virtual_size()
#
# More cases copied from:
# https://github.com/kristapsk/bitcoin-scripts/blob/0b847bec016638e60313ecec2b81f2e8accd311b/tests/tx-vsize.bats # https://github.com/kristapsk/bitcoin-scripts/blob/0b847bec016638e60313ecec2b81f2e8accd311b/tests/tx-vsize.bats
@pytest.mark.parametrize( @pytest.mark.parametrize(
"inaddrtypes, outaddrtypes, size_expected", "inaddrtypes, outaddrtypes, size_expected",
[(["p2pkh"], ["p2pkh"], 192), [(["p2wpkh"], ["p2wsh", "p2wpkh"], 153),
(["p2wsh"], ["p2wpkh", "p2wpkh"], 143),
(["p2wsh", "p2wpkh"], ["p2sh-p2wpkh", "p2wpkh"], 212),
(["p2wsh"], ["p2wsh"], 124),
(["p2pkh"], ["p2pkh"], 192),
(["p2pkh"], ["p2pkh", "p2pkh"], 226), (["p2pkh"], ["p2pkh", "p2pkh"], 226),
(["p2pkh"], ["p2sh-p2wpkh", "p2sh-p2wpkh"], 222), (["p2pkh"], ["p2sh-p2wpkh", "p2sh-p2wpkh"], 222),
(["p2pkh"], ["p2pkh", "p2sh-p2wpkh"], 224), (["p2pkh"], ["p2pkh", "p2sh-p2wpkh"], 224),
(["p2sh-p2wpkh"], ["p2sh-p2wpkh"], 135), (["p2sh-p2wpkh"], ["p2sh-p2wpkh"], 134),
(["p2wpkh"], ["p2wpkh"], 111), (["p2wpkh"], ["p2wpkh"], 110),
]) ])
def test_tx_size_estimate(inaddrtypes, outaddrtypes, size_expected): def test_tx_size_estimate(inaddrtypes, outaddrtypes, size_expected):
# non-sw only inputs result in a single integer return, # non-sw only inputs result in a single integer return,
# segwit inputs return (witness size, non-witness size) # segwit inputs return (witness size, non-witness size)
x = btc.estimate_tx_size(inaddrtypes, outaddrtypes) x = btc.estimate_tx_size(inaddrtypes, outaddrtypes)
if btc.there_is_one_segwit_input(inaddrtypes): if btc.there_is_one_segwit_input(inaddrtypes):
s = int(x[0]/4 + x[1]) s = ceil((x[0] + x[1] * 4)/4.0)
else: else:
s = x s = x
assert s == size_expected assert s == size_expected

4
jmclient/jmclient/wallet.py

@ -8,6 +8,7 @@ import random
import copy import copy
import base64 import base64
import json import json
from math import ceil
from binascii import hexlify, unhexlify from binascii import hexlify, unhexlify
from datetime import datetime, timedelta from datetime import datetime, timedelta
from calendar import timegm from calendar import timegm
@ -113,8 +114,7 @@ def estimate_tx_fee(ins, outs, txtype='p2pkh', outtype=None, extra_bytes=0):
witness_estimate, non_witness_estimate = btc.estimate_tx_size( witness_estimate, non_witness_estimate = btc.estimate_tx_size(
ins, outs) ins, outs)
non_witness_estimate += extra_bytes non_witness_estimate += extra_bytes
return int(int(( return int(int(ceil(non_witness_estimate + 0.25*witness_estimate)*fee_per_kb)/Decimal(1000.0))
non_witness_estimate + 0.25*witness_estimate)*fee_per_kb)/Decimal(1000.0))
def compute_tx_locktime(): def compute_tx_locktime():
# set locktime for best anonset (Core, Electrum) # set locktime for best anonset (Core, Electrum)

6
jmclient/test/test_taker.py

@ -513,15 +513,15 @@ def test_custom_change(setup_taker):
for out in taker.latest_tx.vout: for out in taker.latest_tx.vout:
# input utxo is 200M; amount is 20M; as per logs: # input utxo is 200M; amount is 20M; as per logs:
# totalin=200000000 # totalin=200000000
# my_txfee=13680 <- this estimate ignores address type # my_txfee=13650 <- this estimate ignores address type
# makers_txfee=3000 # makers_txfee=3000
# cjfee_total=12000 => changevalue=179974320 # cjfee_total=12000 => changevalue=179974350
# note that there is a small variation in the size of # note that there is a small variation in the size of
# the transaction (a few bytes) for the different scriptPubKey # the transaction (a few bytes) for the different scriptPubKey
# type, but this is currently ignored in coinjoins by the # type, but this is currently ignored in coinjoins by the
# Taker (not true for direct send operations), hence we get # Taker (not true for direct send operations), hence we get
# the same value for each different output type. # the same value for each different output type.
if out.scriptPubKey == script and out.nValue == 179974320: if out.scriptPubKey == script and out.nValue == 179974350:
# must be only one # must be only one
assert not custom_change_found assert not custom_change_found
custom_change_found = True custom_change_found = True

Loading…
Cancel
Save