def createcmtdata(request): def cmtdatateardown(): shutil.rmtree("cmtdata") request.addfinalizer(cmtdatateardown) if not os.path.exists("cmtdata"): os.makedirs("cmtdata") load_program_config() jm_single().bc_interface = DummyBlockchainInterface() jm_single().config.set("BLOCKCHAIN", "network", "testnet")
def setup_taker(request): def clean(): from twisted.internet import reactor for dc in reactor.getDelayedCalls(): dc.cancel() request.addfinalizer(clean) def cmtdatateardown(): shutil.rmtree("cmtdata") request.addfinalizer(cmtdatateardown) if not os.path.exists("cmtdata"): os.makedirs("cmtdata") load_test_config() jm_single().bc_interface = DummyBlockchainInterface() jm_single().config.set("BLOCKCHAIN", "network", "testnet")
def setup_env_nodeps(monkeypatch): monkeypatch.setattr(jmclient.configure, 'get_blockchain_interface_instance', lambda x: DummyBlockchainInterface()) load_program_config()
def test_on_sig(createcmtdata, dummyaddr, signmethod, schedule): #plan: create a new transaction with known inputs and dummy outputs; #then, create a signature with various inputs, pass in in b64 to on_sig. #in order for it to verify, the DummyBlockchainInterface will have to #return the right values in query_utxo_set #create 2 privkey + utxos that are to be ours privs = [x * 32 + "\x01" for x in [chr(y) for y in range(1, 6)]] utxos = [str(x) * 64 + ":1" for x in range(5)] fake_query_results = [{ 'value': 200000000, 'utxo': utxos[x], 'address': bitcoin.privkey_to_address(privs[x], False, magicbyte=0x6f), 'script': bitcoin.mk_pubkey_script( bitcoin.privkey_to_address(privs[x], False, magicbyte=0x6f)), 'confirms': 20 } for x in range(5)] dbci = DummyBlockchainInterface() dbci.insert_fake_query_results(fake_query_results) jm_single().bc_interface = dbci #make a transaction with all the fake results above, and some outputs outs = [{ 'value': 100000000, 'address': dummyaddr }, { 'value': 899990000, 'address': dummyaddr }] tx = bitcoin.mktx(utxos, outs) de_tx = bitcoin.deserialize(tx) #prepare the Taker with the right intermediate data taker = get_taker(schedule=schedule, sign_method=signmethod) taker.nonrespondants = ["cp1", "cp2", "cp3"] taker.latest_tx = de_tx #my inputs are the first 2 utxos taker.input_utxos = { utxos[0]: { 'address': bitcoin.privkey_to_address(privs[0], False, magicbyte=0x6f), 'value': 200000000 }, utxos[1]: { 'address': bitcoin.privkey_to_address(privs[1], False, magicbyte=0x6f), 'value': 200000000 } } taker.utxos = { None: utxos[:2], "cp1": [utxos[2]], "cp2": [utxos[3]], "cp3": [utxos[4]] } for i in range(2): # placeholders required for my inputs taker.latest_tx['ins'][i]['script'] = 'deadbeef' #to prepare for my signing, need to mark cjaddr: taker.my_cj_addr = dummyaddr #make signatures for the last 3 fake utxos, considered as "not ours": tx3 = bitcoin.sign(tx, 2, privs[2]) sig3 = b64encode( bitcoin.deserialize(tx3)['ins'][2]['script'].decode('hex')) taker.on_sig("cp1", sig3) tx4 = bitcoin.sign(tx, 3, privs[3]) sig4 = b64encode( bitcoin.deserialize(tx4)['ins'][3]['script'].decode('hex')) taker.on_sig("cp2", sig4) tx5 = bitcoin.sign(tx, 4, privs[4]) #Before completing with the final signature, which will trigger our own #signing, try with an injected failure of query utxo set, which should #prevent this signature being accepted. dbci.setQUSFail(True) sig5 = b64encode( bitcoin.deserialize(tx5)['ins'][4]['script'].decode('hex')) taker.on_sig("cp3", sig5) #allow it to succeed, and try again dbci.setQUSFail(False) #this should succeed and trigger the we-sign code taker.on_sig("cp3", sig5)
def test_get_utxo_info(): load_program_config() jm_single().config.set("BLOCKCHAIN", "network", "mainnet") dbci = DummyBlockchainInterface() privkey = "L1RrrnXkcKut5DEMwtDthjwRcTTwED36thyL1DebVrKuwvohjMNi" #to verify use from_wif_privkey and privkey_to_address iaddr = "1LDsjB43N2NAQ1Vbc2xyHca4iBBciN8iwC" fakeutxo = "aa"*32+":08" fake_query_results = [{'value': 200000000, 'address': iaddr, 'utxo': fakeutxo, 'confirms': 20}] dbci.insert_fake_query_results(fake_query_results) jm_single().bc_interface = dbci u, priv = get_utxo_info(fakeutxo + "," + privkey) assert u == fakeutxo assert priv == privkey #invalid format with pytest.raises(Exception) as e_info: u, priv = get_utxo_info(fakeutxo + privkey) #invalid index fu2 = "ab"*32 + ":00004" with pytest.raises(Exception) as e_info: u, priv = get_utxo_info(fu2 + "," + privkey) #invalid privkey p2 = privkey[:-1] + 'j' with pytest.raises(Exception) as e_info: u, priv = get_utxo_info(fakeutxo + "," + p2) utxodatas = [(fakeutxo, privkey)] retval = validate_utxo_data(utxodatas, False) assert retval #try to retrieve retval = validate_utxo_data(utxodatas, True) assert retval[0] == (fakeutxo, 200000000) fake_query_results[0]['address'] = "fakeaddress" dbci.insert_fake_query_results(fake_query_results) #validate should fail for wrong address retval = validate_utxo_data(utxodatas, False) assert not retval #remove fake query result and trigger not found dbci.fake_query_results = None dbci.setQUSFail(True) retval = validate_utxo_data(utxodatas, False) assert not retval dbci.setQUSFail(False)
def setup_env_nodeps(monkeypatch): monkeypatch.setattr(jmclient.configure, 'get_blockchain_interface_instance', lambda x: DummyBlockchainInterface()) btc.select_chain_params("bitcoin/regtest") load_test_config()
def test_get_utxo_info(): load_test_config() # this test tests mainnet keys, so temporarily switch network select_chain_params("bitcoin") jm_single().config.set("BLOCKCHAIN", "network", "mainnet") dbci = DummyBlockchainInterface() privkey = "L1RrrnXkcKut5DEMwtDthjwRcTTwED36thyL1DebVrKuwvohjMNi" #to verify use from_wif_privkey and privkey_to_address iaddr = "bc1q6tvmnmetj8vfz98vuetpvtuplqtj4uvvwjgxxc" fakeutxo = "aa" * 32 + ":08" success, fakeutxo_bin = utxostr_to_utxo(fakeutxo) assert success fake_query_results = [{ 'value': 200000000, 'script': BTC_P2WPKH.address_to_script(iaddr), 'utxo': fakeutxo_bin, 'confirms': 20 }] dbci.insert_fake_query_results(fake_query_results) jm_single().bc_interface = dbci u, priv = get_utxo_info(fakeutxo + "," + privkey) assert u == fakeutxo assert priv == privkey #invalid format with pytest.raises(Exception): u, priv = get_utxo_info(fakeutxo + privkey) #invalid index fu2 = "ab" * 32 + ":-1" with pytest.raises(Exception): u, priv = get_utxo_info(fu2 + "," + privkey) #invalid privkey p2 = privkey[:-1] + 'j' with pytest.raises(Exception): u, priv = get_utxo_info(fakeutxo + "," + p2) utxodatas = [(fakeutxo_bin, privkey)] retval = validate_utxo_data(utxodatas, False) assert retval #try to retrieve retval = validate_utxo_data(utxodatas, True) assert retval[0] == (fakeutxo_bin, 200000000) fake_query_results[0]['script'] = hextobin( "76a91479b000887626b294a914501a4cd226b58b23598388ac") dbci.insert_fake_query_results(fake_query_results) #validate should fail for wrong address retval = validate_utxo_data(utxodatas, False) assert not retval #remove fake query result and trigger not found dbci.fake_query_results = None dbci.setQUSFail(True) retval = validate_utxo_data(utxodatas, False) assert not retval dbci.setQUSFail(False) select_chain_params("bitcoin/regtest") jm_single().config.set("BLOCKCHAIN", "network", "regtest")
def test_on_sig(setup_taker, dummyaddr, schedule): #plan: create a new transaction with known inputs and dummy outputs; #then, create a signature with various inputs, pass in in b64 to on_sig. #in order for it to verify, the DummyBlockchainInterface will have to #return the right values in query_utxo_set utxos = [(struct.pack(b"B", x) * 32, 1) for x in range(5)] #create 2 privkey + utxos that are to be ours privs = [x*32 + b"\x01" for x in [struct.pack(b'B', y) for y in range(1,6)]] scripts = [BTC_P2PKH.key_to_script(privs[x]) for x in range(5)] addrs = [BTC_P2PKH.privkey_to_address(privs[x]) for x in range(5)] fake_query_results = [{'value': 200000000, 'utxo': utxos[x], 'address': addrs[x], 'script': scripts[x], 'confirms': 20} for x in range(5)] dbci = DummyBlockchainInterface() dbci.insert_fake_query_results(fake_query_results) jm_single().bc_interface = dbci #make a transaction with all the fake results above, and some outputs outs = [{'value': 100000000, 'address': dummyaddr}, {'value': 899990000, 'address': dummyaddr}] tx = bitcoin.mktx(utxos, outs) # since tx will be updated as it is signed, unlike in real life # (where maker signing operation doesn't happen here), we'll create # a second copy without the signatures: tx2 = bitcoin.mktx(utxos, outs) #prepare the Taker with the right intermediate data taker = get_taker(schedule=schedule) taker.nonrespondants=["cp1", "cp2", "cp3"] taker.latest_tx = tx #my inputs are the first 2 utxos taker.input_utxos = {utxos[0]: {'address': addrs[0], 'script': scripts[0], 'value': 200000000}, utxos[1]: {'address': addrs[1], 'script': scripts[1], 'value': 200000000}} taker.utxos = {None: utxos[:2], "cp1": [utxos[2]], "cp2": [utxos[3]], "cp3":[utxos[4]]} for i in range(2): # placeholders required for my inputs taker.latest_tx.vin[i].scriptSig = bitcoin.CScript(hextobin('deadbeef')) tx2.vin[i].scriptSig = bitcoin.CScript(hextobin('deadbeef')) #to prepare for my signing, need to mark cjaddr: taker.my_cj_addr = dummyaddr #make signatures for the last 3 fake utxos, considered as "not ours": sig, msg = bitcoin.sign(tx2, 2, privs[2]) assert sig, "Failed to sign: " + msg sig3 = b64encode(tx2.vin[2].scriptSig) taker.on_sig("cp1", sig3) #try sending the same sig again; should be ignored taker.on_sig("cp1", sig3) sig, msg = bitcoin.sign(tx2, 3, privs[3]) assert sig, "Failed to sign: " + msg sig4 = b64encode(tx2.vin[3].scriptSig) #try sending junk instead of cp2's correct sig assert not taker.on_sig("cp2", str("junk")), "incorrectly accepted junk signature" taker.on_sig("cp2", sig4) sig, msg = bitcoin.sign(tx2, 4, privs[4]) assert sig, "Failed to sign: " + msg #Before completing with the final signature, which will trigger our own #signing, try with an injected failure of query utxo set, which should #prevent this signature being accepted. dbci.setQUSFail(True) sig5 = b64encode(tx2.vin[4].scriptSig) assert not taker.on_sig("cp3", sig5), "incorrectly accepted sig5" #allow it to succeed, and try again dbci.setQUSFail(False) #this should succeed and trigger the we-sign code taker.on_sig("cp3", sig5)