You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

178 lines
5.7 KiB

#!/usr/bin/env python
import jmbitcoin as btc
from jmclient import Maker, get_p2sh_vbyte, get_p2pk_vbyte, \
load_test_config, jm_single, WalletService
import jmclient
from commontest import DummyBlockchainInterface
from test_taker import DummyWallet
import struct
import binascii
from itertools import chain
import pytest
class OfflineMaker(Maker):
def try_to_create_my_orders(self):
self.sync_wait_loop.stop()
def construct_tx_offerlist(cjaddr, changeaddr, maker_utxos, maker_utxos_value,
cj_value, ordertype):
offer = {
'cjfee': '0',
'maxsize': cj_value*3,
'minsize': 7500000,
'oid': 0,
'ordertype': ordertype,
'txfee': 0
}
utxos = { utxo['outpoint']['hash'] + ':' + str(utxo['outpoint']['index']):
{'utxo': utxo, 'value': maker_utxos_value} for utxo in maker_utxos }
offerlist = {
'utxos': utxos,
'cjaddr': cjaddr,
'changeaddr': changeaddr,
'amount': cj_value,
'offer': offer
}
return offerlist
def create_tx_inputs(count=1):
inp = []
for i in range(count):
inp.append({'outpoint': {'hash': '0'*64, 'index': i},
'script': '',
'sequence': 4294967295})
return inp
def create_tx_outputs(*scripts_amount):
outp = []
for script, amount in scripts_amount:
outp.append({'script': script, 'value': amount})
return outp
def address_p2pkh_generator():
return get_address_generator(b'\x76\xa9\x14', b'\x88\xac', get_p2pk_vbyte())
def address_p2sh_generator():
return get_address_generator(b'\xa9\x14', b'\x87', get_p2sh_vbyte())
def get_address_generator(script_pre, script_post, vbyte):
counter = 0
while True:
script = script_pre + struct.pack(b'=LQQ', 0, 0, counter) + script_post
addr = btc.script_to_address(script, vbyte)
yield addr, binascii.hexlify(script).decode('ascii')
counter += 1
def create_tx_and_offerlist(cj_addr, cj_change_addr, other_output_scripts,
cj_script=None, cj_change_script=None, offertype='swreloffer'):
assert len(other_output_scripts) % 2 == 0, "bug in test"
cj_value = 100000000
maker_total_value = cj_value*3
if cj_script is None:
cj_script = btc.address_to_script(cj_addr)
if cj_change_script is None:
cj_change_script = btc.address_to_script(cj_change_addr)
inputs = create_tx_inputs(3)
outputs = create_tx_outputs(
(cj_script, cj_value),
(cj_change_script, maker_total_value - cj_value), # cjfee=0, txfee=0
*((script, cj_value + (i%2)*(50000000+i)) \
for i, script in enumerate(other_output_scripts))
)
maker_utxos = [inputs[0]]
tx = btc.deserialize(btc.mktx(inputs, outputs))
offerlist = construct_tx_offerlist(cj_addr, cj_change_addr, maker_utxos,
maker_total_value, cj_value, offertype)
return tx, offerlist
def test_verify_unsigned_tx_sw_valid(setup_env_nodeps):
jm_single().config.set("POLICY", "segwit", "true")
p2sh_gen = address_p2sh_generator()
p2pkh_gen = address_p2pkh_generator()
wallet = DummyWallet()
maker = OfflineMaker(WalletService(wallet))
cj_addr, cj_script = next(p2sh_gen)
changeaddr, cj_change_script = next(p2sh_gen)
# test standard cj
tx, offerlist = create_tx_and_offerlist(cj_addr, changeaddr,
[next(p2sh_gen)[1] for s in range(4)], cj_script, cj_change_script)
assert maker.verify_unsigned_tx(tx, offerlist) == (True, None), "standard sw cj"
# test cj with mixed outputs
tx, offerlist = create_tx_and_offerlist(cj_addr, changeaddr,
list(chain((next(p2sh_gen)[1] for s in range(3)),
(next(p2pkh_gen)[1] for s in range(1)))),
cj_script, cj_change_script)
assert maker.verify_unsigned_tx(tx, offerlist) == (True, None), "sw cj with p2pkh output"
# test cj with only p2pkh outputs
tx, offerlist = create_tx_and_offerlist(cj_addr, changeaddr,
[next(p2pkh_gen)[1] for s in range(4)], cj_script, cj_change_script)
assert maker.verify_unsigned_tx(tx, offerlist) == (True, None), "sw cj with only p2pkh outputs"
def test_verify_unsigned_tx_nonsw_valid(setup_env_nodeps):
jm_single().config.set("POLICY", "segwit", "false")
p2sh_gen = address_p2sh_generator()
p2pkh_gen = address_p2pkh_generator()
wallet = DummyWallet()
maker = OfflineMaker(WalletService(wallet))
cj_addr, cj_script = next(p2pkh_gen)
changeaddr, cj_change_script = next(p2pkh_gen)
# test standard cj
tx, offerlist = create_tx_and_offerlist(cj_addr, changeaddr,
[next(p2pkh_gen)[1] for s in range(4)], cj_script, cj_change_script, 'reloffer')
assert maker.verify_unsigned_tx(tx, offerlist) == (True, None), "standard nonsw cj"
# test cj with mixed outputs
tx, offerlist = create_tx_and_offerlist(cj_addr, changeaddr,
list(chain((next(p2sh_gen)[1] for s in range(1)),
(next(p2pkh_gen)[1] for s in range(3)))),
cj_script, cj_change_script, 'reloffer')
assert maker.verify_unsigned_tx(tx, offerlist) == (True, None), "nonsw cj with p2sh output"
# test cj with only p2sh outputs
tx, offerlist = create_tx_and_offerlist(cj_addr, changeaddr,
[next(p2sh_gen)[1] for s in range(4)], cj_script, cj_change_script, 'reloffer')
assert maker.verify_unsigned_tx(tx, offerlist) == (True, None), "nonsw cj with only p2sh outputs"
@pytest.fixture
def setup_env_nodeps(monkeypatch):
monkeypatch.setattr(jmclient.configure, 'get_blockchain_interface_instance',
lambda x: DummyBlockchainInterface())
load_test_config()