Browse Source
Also, some minor changes: filter_orders_callback taken outside Taker since it involves user input necessarily. Related, answeryes removed from module, can be done outside. Donation code explicitly removed from all code branches for now. A couple of very minor changes thrown up from testing. Coverage of Taker now 100%, will work on the rest of jmclient.master
6 changed files with 748 additions and 49 deletions
@ -0,0 +1,190 @@
|
||||
#orderbook |
||||
t_orderbook = [{u'counterparty': u'J5FA1Gj7Ln4vSGne', u'ordertype': u'reloffer', u'oid': 0, |
||||
u'minsize': 7500000, u'txfee': 1000, u'maxsize': 599972700, u'cjfee': u'0.0002'}, |
||||
{u'counterparty': u'J5CFffuuewjG44UJ', u'ordertype': u'reloffer', u'oid': 0, |
||||
u'minsize': 7500000, u'txfee': 1000, u'maxsize': 599972700, u'cjfee': u'0.0002'}, |
||||
{u'counterparty': u'J55z23xdjxJjC7er', u'ordertype': u'reloffer', u'oid': 0, |
||||
u'minsize': 7500000, u'txfee': 1000, u'maxsize': 599972700, u'cjfee': u'0.0002'}, |
||||
{u'counterparty': u'J54Ghp5PXCdY9H3t', u'ordertype': u'reloffer', u'oid': 0, |
||||
u'minsize': 7500000, u'txfee': 1000, u'maxsize': 599972700, u'cjfee': u'0.0002'}, |
||||
{u'counterparty': u'J559UPUSLLjHJpaB', u'ordertype': u'reloffer', u'oid': 0, |
||||
u'minsize': 7500000, u'txfee': 1000, u'maxsize': 599972700, u'cjfee': u'0.0002'}, |
||||
{u'counterparty': u'J5cBx1FwUVh9zzoO', u'ordertype': u'reloffer', u'oid': 0, |
||||
u'minsize': 7500000, u'txfee': 1000, u'maxsize': 599972700, u'cjfee': u'0.0002'}] |
||||
|
||||
t_dest_addr = "mvw1NazKDRbeNufFANqpYNAANafsMC2zVU" |
||||
|
||||
t_chosen_orders = {u'J559UPUSLLjHJpaB': {u'cjfee': u'0.0002', |
||||
u'counterparty': u'J559UPUSLLjHJpaB', |
||||
u'maxsize': 599972700, |
||||
u'minsize': 7500000, |
||||
u'oid': 0, |
||||
u'ordertype': u'reloffer', |
||||
u'txfee': 1000}, |
||||
u'J55z23xdjxJjC7er': {u'cjfee': u'0.0002', |
||||
u'counterparty': u'J55z23xdjxJjC7er', |
||||
u'maxsize': 599972700, |
||||
u'minsize': 7500000, |
||||
u'oid': 0, |
||||
u'ordertype': u'reloffer', |
||||
u'txfee': 1000}, |
||||
u'J5CFffuuewjG44UJ': {u'cjfee': u'0.0002', |
||||
u'counterparty': u'J5CFffuuewjG44UJ', |
||||
u'maxsize': 599972700, |
||||
u'minsize': 7500000, |
||||
u'oid': 0, |
||||
u'ordertype': u'reloffer', |
||||
u'txfee': 1000}} |
||||
|
||||
""" |
||||
2016-12-01 15:27:33,351 [MainThread ] [INFO ] total cj fee = 63000 |
||||
2016-12-01 15:27:33,351 [MainThread ] [INFO ] total coinjoin fee = 0.0573% |
||||
2016-12-01 15:27:34,887 [MainThread ] [DEBUG] INFO:Preparing bitcoin data.. |
||||
2016-12-01 15:27:34,888 [MainThread ] [DEBUG] rpc: getaccount ['myzi6K9vt88rdiXpYayfJkU1x33G1wz2fP'] |
||||
2016-12-01 15:27:34,889 [MainThread ] [DEBUG] total estimated amount spent = 110093000 |
||||
""" |
||||
t_utxos_by_mixdepth = {0: {u'534b635ed8891f16c4ec5b8236ae86164783903e8e8bb47fa9ef2ca31f3c2d7a:0': {'address': u'mrcNu71ztWjAQA6ww9kHiW3zBWSQidHXTQ', |
||||
'value': 200000000}}, |
||||
1: {u'0780d6e5e381bff01a3519997bb4fcba002493103a198fde334fd264f9835d75:1': {'address': u'mvtY8DVgn3TtvjHbVsauYoSQjAhNqVyqmM', |
||||
'value': 200000000}, |
||||
u'7e574db96a4d43a99786b3ea653cda9e4388f377848f489332577e018380cff1:0': {'address': u'n3nELhmU2D7ebGYzJnGFWgVDK3cYErmTcQ', |
||||
'value': 200000000}, |
||||
u'dd9711a2ef340750db21efb761f5f7d665d94b312332dc354e252c77e9c48349:0': {'address': u'mxeLuX8PP7qLkcM8uarHmdZyvP1b5e1Ynf', |
||||
'value': 200000000}}, |
||||
2: {}, |
||||
3: {}, |
||||
4: {}} |
||||
|
||||
t_selected_utxos = [{'utxo': u'0780d6e5e381bff01a3519997bb4fcba002493103a198fde334fd264f9835d75:1', |
||||
'value': 200000000}] |
||||
|
||||
t_generated_podle = {'P': '025a2e04dc6bd5f58fe4eb13045b27f0dd17c39524264639f48607347cf6d69c4e', |
||||
'P2': '0223e54e9917d8482f1b54ead8e941907c17051b95397e8bc110adc6681d8d44c8', |
||||
'commit': 'aa0545c9ed918e66f86df467c96a4978529b836aa4688df682a2db4e27d4ed9d', |
||||
'e': '5b7ab1fa21287bbf0df4a0c46f6c31c3f17887ee9ea6ae584fc3a861ae9f1e9d', |
||||
'sig': 'ebe25d7b2d667de802677c30c6fea07386f0cd67d4e4c795e4a6ebc39b21eb39', |
||||
'used': 'False', |
||||
'utxo': u'0780d6e5e381bff01a3519997bb4fcba002493103a198fde334fd264f9835d75:1'} |
||||
|
||||
t_maker_response = {"J559UPUSLLjHJpaB": |
||||
[["03243f4a659e278a1333f8308f6aaf32db4692ee7df0340202750fd6c09150f6:1"], |
||||
"03a2d1cbe977b1feaf8d0d5cc28c686859563d1520b28018be0c2661cf1ebe4857", |
||||
"mrKTGvFfYUEqk52qPKUroumZJcpjHLQ6pn", |
||||
"mxPnzFkCQpPzVQdajNLoT4us5pTPsQZZZp", |
||||
"MEQCIBeGrtxxVrj5tSUX6vEetmzE8nRBG/guSXq3SrqypIt5AiAnIZzDUXu8DtODgF2p1Bo27L8VcG1GJSfatZbS23YZQQ==", |
||||
"5bcc7ae1a3530e454812668620aced47d774bf06a1f5870d531422a1a958b629"], |
||||
"J55z23xdjxJjC7er": |
||||
[["498faa8b22534f3b443c6b0ce202f31e12f21668b4f0c7a005146808f250d4c3:0"], |
||||
"02b4b749d54e96b04066b0803e372a43d6ffa16e75a001ae0ed4b235674ab286be", |
||||
"mhatyHdna3Qt5FtnfwWaMVV1dohCaDYF3T", |
||||
"mjJoVN2HCUGVDvNebiFnHdB3zF56bxQm5z", |
||||
"MEQCIBlMF7DRbhr14e74He9m+UYjR5y8jjvP7TvUh8valebmAiBoIGjl436fsYim9pKSTbCKiBmT82hQ98LvIOGSLprk0A==", |
||||
"8204d1cba30d4cdabab16a5e8d10d17464e24c78a6f887ae2d920b223c030d28"], |
||||
"J5CFffuuewjG44UJ": |
||||
[["3f3ea820d706e08ad8dc1d2c392c98facb1b067ae4c671043ae9461057bd2a3c:1"], |
||||
"023bcbafb4f68455e0d1d117c178b0e82a84e66414f0987453d78da034b299c3a9", |
||||
"mpAEocXy8ckcJBo3fhQg9Mv1kfEzAuUivX", |
||||
"n29NWbsyq5MjCMC5ykjStd78zwfjvCvJJZ", |
||||
"MEUCIQDAM5Aa0aU5iKI0b9YnNtwH0m+6sz3zeTL8f398CPjuQAIgLeU9mCJX8SupNNMkA+bsUJeRYe3kiLnzq3OlmXTxck0=", |
||||
"7377d03477485884e0129dbdb2d79f4956f5b74366d805385b6f127509a8433f"]} |
||||
|
||||
""" |
||||
2016-12-01 15:27:39,914 [MainThread ] [DEBUG] rpc: gettxout [u'03243f4a659e278a1333f8308f6aaf32db4692ee7df0340202750fd6c09150f6', 1, False] |
||||
2016-12-01 15:27:39,915 [MainThread ] [DEBUG] fee breakdown for J559UPUSLLjHJpaB totalin=200000000 cjamount=110000000 txfee=1000 realcjfee=22000 |
||||
2016-12-01 15:27:39,915 [MainThread ] [DEBUG] rpc: gettxout [u'498faa8b22534f3b443c6b0ce202f31e12f21668b4f0c7a005146808f250d4c3', 0, False] |
||||
2016-12-01 15:27:39,915 [MainThread ] [DEBUG] fee breakdown for J55z23xdjxJjC7er totalin=200000000 cjamount=110000000 txfee=1000 realcjfee=22000 |
||||
2016-12-01 15:27:39,916 [MainThread ] [DEBUG] rpc: gettxout [u'3f3ea820d706e08ad8dc1d2c392c98facb1b067ae4c671043ae9461057bd2a3c', 1, False] |
||||
2016-12-01 15:27:39,916 [MainThread ] [DEBUG] fee breakdown for J5CFffuuewjG44UJ totalin=200000000 cjamount=110000000 txfee=1000 realcjfee=22000 |
||||
2016-12-01 15:27:39,916 [MainThread ] [DEBUG] INFO:Got all parts, enough to build a tx |
||||
2016-12-01 15:27:39,917 [MainThread ] [DEBUG] Estimated transaction size: 870 |
||||
2016-12-01 15:27:39,917 [MainThread ] [DEBUG] rpc: estimatefee [3] |
||||
2016-12-01 15:27:39,917 [MainThread ] [DEBUG] got estimated tx bytes: 870 |
||||
2016-12-01 15:27:39,917 [MainThread ] [INFO ] Based on initial guess: 30000, we estimated a miner fee of: 26100 |
||||
2016-12-01 15:27:39,918 [MainThread ] [INFO ] fee breakdown for me totalin=200000000 my_txfee=23100 makers_txfee=3000 cjfee_total=66000 => changevalue=89910900 |
||||
""" |
||||
|
||||
t_obtained_tx = {'ins': [{'outpoint': {'hash': '03243f4a659e278a1333f8308f6aaf32db4692ee7df0340202750fd6c09150f6', |
||||
'index': 1}, |
||||
'script': '', |
||||
'sequence': 4294967295}, |
||||
{'outpoint': {'hash': '3f3ea820d706e08ad8dc1d2c392c98facb1b067ae4c671043ae9461057bd2a3c', |
||||
'index': 1}, |
||||
'script': '', |
||||
'sequence': 4294967295}, |
||||
{'outpoint': {'hash': '498faa8b22534f3b443c6b0ce202f31e12f21668b4f0c7a005146808f250d4c3', |
||||
'index': 0}, |
||||
'script': '', |
||||
'sequence': 4294967295}, |
||||
{'outpoint': {'hash': '0780d6e5e381bff01a3519997bb4fcba002493103a198fde334fd264f9835d75', |
||||
'index': 1}, |
||||
'script': '', |
||||
'sequence': 4294967295}], |
||||
'locktime': 0, |
||||
'outs': [{'script': '76a914767c956efe6092a775fea39a06d1cac9aae956d788ac', |
||||
'value': 110000000}, |
||||
{'script': '76a914cab20e3270988ac99651b8f079a3b4c93b996a6888ac', |
||||
'value': 89910900}, |
||||
{'script': '76a914b91f75254b5fa1510cc944a2206ed72235d0d88188ac', |
||||
'value': 90021000}, |
||||
{'script': '76a914a916707952c2df28a3abf3ee692dfbbd5a4d74dc88ac', |
||||
'value': 110000000}, |
||||
{'script': '76a914e245b480b46bcbc9d13e68766ad19909decd135288ac', |
||||
'value': 90021000}, |
||||
{'script': '76a91416af241bb1db02dfd7c65989bbab190ac489ccc188ac', |
||||
'value': 110000000}, |
||||
{'script': '76a9142994295a9d4d083eb792e669e3211007dc78928888ac', |
||||
'value': 90021000}, |
||||
{'script': '76a9145ece2dac945c8ff5b2b6635360ca0478ade305d488ac', |
||||
'value': 110000000}], |
||||
'version': 1} |
||||
|
||||
#signatures from makers |
||||
""" |
||||
nick=J5CFffuuewjG44UJ message=!sig xH9IAMo2fvG+g+DAbLNOPsGsJCDm6r+ZY5QM7p+SRsixbqSwXcBQAn7Mnw1rS+uGlrJkM8ossX5VHKjdKDhTXQVLawR7XgiVFFFiO+/FjdFhqVuS4Q/NgOlb7nCBe/UaBebd9NpuURG+8u/V+46jtqKRtVsSO1+QZQBt2nSpYCqxWIjxMowRxS4O/zlrOVbyjv/AjchOajufKJwckkrkJDyQDYlUdW+eqs43tf0XsJ9k4NHRVVHAQQ== 036558f550b1d398d2325d892e50ef25b0f663ae13f70d0b304a15f07030061ace MEUCIQCE9MgU+HfcHkKE8zNzNeCEdDBJuQatA6C2sTJ9mVKK7wIgX4w9r0tz4s9qeuW0UjNliDatJ4X7pS3/atADSqPat0U= |
||||
nick=J559UPUSLLjHJpaB message=!sig geHTf1n88eKeUnVOj7bIrJF1KFCN03IQhZD0cR17Q7jPSn2DZrrvMaRNkjZRyF+zGnWFwd69kwLRU0ftCaMf/3lw+05UovVCREiyXWUtPJa7XAY2NW4iMmTnGTp8f9RLgDcDhiZayKXTpzBDC9r6WAt6wiD0lej5uw7dmluKSUyfXW8sOYPmLm4iJAPcbGeJiQfiR9zBeX8w+6Kz4bkaiue41SzQP/h9avPV2XIX4kVQQ3jLfQyHww== 038f90ab260df440cef82a981146b509eb9df019884e145158230e8babc17d7be4 MEQCIEo5Pau9zqW2lw+B2AYTYuTO5TDbBkgsOk0bqT+SQctKAiBO1nbsmYTy7E0Qd7jAxko1Gq6Yk0Q6DerByuEuk5IBSQ== |
||||
nick=J55z23xdjxJjC7er message=!sig A5CWvqmYCOiZBEEi9iHVpQL0oO9B7VIIzuU9QhkzXOw+iD916C9b+Yk3eTxrtf+qaLARQ7eui6zdPNek95EdmqCEqM/myeeuBVSy9KrcB9xU0sdnuCu4+g13jVe9Pkvd1iizZ8GCNP7SejEzeltNr0a1lR+M0kKtj4XI+nDTxhisSzL8PDXsqoOMcrDjegna3TZsJeKviu8r/1T/zWwTQtRCXqruLnflqXNLtZoyFmoaO1GurgkNHA== 029a8beadec242f04f2295787ac0175b960e2d68d115ec65c4310de7ce3fa2cec0 MEQCIHpTxVkwtvm7agbp47Z5V0We8jxXkfZDUFsW2tZwTZdHAiA9JnYvo74hF3RihzHw2l+ufTOmC/3ddBpxkB9+AdZvzA== |
||||
""" |
||||
|
||||
""" |
||||
2016-12-01 15:27:39,921 [MainThread ] [DEBUG] INFO:Built tx, sending to counterparties. |
||||
2016-12-01 15:27:39,968 [MainThread ] [DEBUG] rpc: gettxout ['03243f4a659e278a1333f8308f6aaf32db4692ee7df0340202750fd6c09150f6', 1, False] |
||||
2016-12-01 15:27:39,968 [MainThread ] [DEBUG] rpc: gettxout ['3f3ea820d706e08ad8dc1d2c392c98facb1b067ae4c671043ae9461057bd2a3c', 1, False] |
||||
2016-12-01 15:27:39,969 [MainThread ] [DEBUG] rpc: gettxout ['498faa8b22534f3b443c6b0ce202f31e12f21668b4f0c7a005146808f250d4c3', 0, False] |
||||
2016-12-01 15:27:39,971 [MainThread ] [DEBUG] found good sig at index=1 |
||||
2016-12-01 15:27:39,971 [MainThread ] [DEBUG] nick = J5CFffuuewjG44UJ sent all sigs, removing from nonrespondant list |
||||
2016-12-01 15:27:39,971 [MainThread ] [DEBUG] rpc: gettxout ['03243f4a659e278a1333f8308f6aaf32db4692ee7df0340202750fd6c09150f6', 1, False] |
||||
2016-12-01 15:27:39,972 [MainThread ] [DEBUG] rpc: gettxout ['498faa8b22534f3b443c6b0ce202f31e12f21668b4f0c7a005146808f250d4c3', 0, False] |
||||
2016-12-01 15:27:39,973 [MainThread ] [DEBUG] found good sig at index=0 |
||||
2016-12-01 15:27:39,973 [MainThread ] [DEBUG] nick = J559UPUSLLjHJpaB sent all sigs, removing from nonrespondant list |
||||
2016-12-01 15:27:43,937 [MainThread ] [DEBUG] rpc: gettxout ['498faa8b22534f3b443c6b0ce202f31e12f21668b4f0c7a005146808f250d4c3', 0, False] |
||||
2016-12-01 15:27:43,938 [MainThread ] [DEBUG] found good sig at index=2 |
||||
2016-12-01 15:27:43,938 [MainThread ] [DEBUG] nick = J55z23xdjxJjC7er sent all sigs, removing from nonrespondant list |
||||
2016-12-01 15:27:43,938 [MainThread ] [DEBUG] all makers have sent their signatures |
||||
2016-12-01 15:27:43,938 [MainThread ] [DEBUG] INFO:Transaction is valid, signing.. |
||||
2016-12-01 15:27:43,943 [MainThread ] [DEBUG] |
||||
""" |
||||
|
||||
t_raw_signed_tx = "0100000004f65091c0d60f75020234f07dee9246db32af6a8f30f833138a279e654a3f2403010000006b483045022100ad522388ce9eacf2760e4d6bd6a114a0e15b88879b430fbb2e60df947494df2402201f49338726599eb0980873aef268d8d890de2792967ff28f0c11eb35e54ff07a012103a2d1cbe977b1feaf8d0d5cc28c686859563d1520b28018be0c2661cf1ebe4857ffffffff3c2abd571046e93a0471c6e47a061bcbfa982c392c1ddcd88ae006d720a83e3f010000006a473044022012bbfa6ef7b0416e00001d90b022d6663f5fd57d9a07bb70b887510f7c44902d022059b382bfb1ff5588a518fc69c55b2ff67d3facc11088e984d7c09c336d4875330121023bcbafb4f68455e0d1d117c178b0e82a84e66414f0987453d78da034b299c3a9ffffffffc3d450f208681405a0c7f0b46816f2121ef302e20c6b3c443b4f53228baa8f49000000006b48304502210081019ea7b68130da4230fd748668c776043004843de50e07bb5fcb42e7632aed022000a34878274e583eec64815d1b587e7fbcd9ac714e722773ac1e69f1209f2e10012102b4b749d54e96b04066b0803e372a43d6ffa16e75a001ae0ed4b235674ab286beffffffff755d83f964d24f33de8f193a10932400bafcb47b9919351af0bf81e3e5d68007010000006b483045022100add68e9532a50ca5585999290531f26e515bdf3d001519b0de8dd6b981daec7f02200b34c58ce61e6673c9efc5bf82cacd4d02673bc1c6cbaba45b5c65579776b8180121025a2e04dc6bd5f58fe4eb13045b27f0dd17c39524264639f48607347cf6d69c4effffffff0880778e06000000001976a914767c956efe6092a775fea39a06d1cac9aae956d788ac74ee5b05000000001976a914cab20e3270988ac99651b8f079a3b4c93b996a6888ac889c5d05000000001976a914b91f75254b5fa1510cc944a2206ed72235d0d88188ac80778e06000000001976a914a916707952c2df28a3abf3ee692dfbbd5a4d74dc88ac889c5d05000000001976a914e245b480b46bcbc9d13e68766ad19909decd135288ac80778e06000000001976a91416af241bb1db02dfd7c65989bbab190ac489ccc188ac889c5d05000000001976a9142994295a9d4d083eb792e669e3211007dc78928888ac80778e06000000001976a9145ece2dac945c8ff5b2b6635360ca0478ade305d488ac00000000" |
||||
t_txid = "4d5bfad9bbfb93eb1e25fb2e6c832323d1bf39e63f6ed2319b65e85354c7ca70" |
||||
|
||||
t_dummy_ext = {"used": [], "external": { |
||||
"79f1b8df7d0978f30028487c6c4e0eae96d1aa18e01f13bb4cba6788590cd431:1": { |
||||
"reveal": { |
||||
"1": { |
||||
"P2": "0329d4b4bb28c1a0747c1a5daad59763a9021b5e1fa957887a90c7849789a683b6", |
||||
"s": "a303cad939fb773dd16a81c44f210afe0b985a2cf9a63b033139455b70c77be6", |
||||
"e": "64f5b9861b95434ab84bd044b93a28f85ea94b474237992d899bd4302eef3820" |
||||
}, |
||||
"0": { |
||||
"P2": "02681ed66595daf98b12d6d69d8afb8d14a531eeaea1161bce8b9f2666ea55f157", |
||||
"s": "ed994ad173431bd0f53c82fee70d202e9c2adce492b6226d3cb4116cc3a08383", |
||||
"e": "1dd7f56fe83ca66e89b3ec3b73fa44edacab0ef4524652c415065dbf91500c85" |
||||
}, |
||||
"2": { |
||||
"P2": "02cdd5ced7e79bdb651d6d1883e0047509793a9a9e3da4ae516b8a853b9cdd8e98", |
||||
"s": "39a19287c4bacc823559d0e1b907e311c31d8a13f45fe30d10b133561113515c", |
||||
"e": "a0e7cd319c7e51c6f9e503e95d08c3d2398f9b546c2d64178b6c113c63c29d78" |
||||
} |
||||
}, |
||||
"P": "033749d513d0e0239a75892556a6ce01c3e48f82e75169129abe8ef370ab992c94" |
||||
}}} |
||||
@ -0,0 +1,510 @@
|
||||
#!/usr/bin/env python |
||||
from __future__ import print_function |
||||
from jmclient import AbstractWallet |
||||
from jmclient import BlockchainInterface |
||||
from jmclient import Taker |
||||
import jmbitcoin as bitcoin |
||||
import binascii |
||||
import os |
||||
import copy |
||||
import shutil |
||||
import pytest |
||||
import json |
||||
from base64 import b64encode |
||||
from jmclient import (load_program_config, jm_single, set_commitment_file, |
||||
get_commitment_file) |
||||
from taker_test_data import (t_utxos_by_mixdepth, t_selected_utxos, t_orderbook, |
||||
t_maker_response, t_chosen_orders, t_dummy_ext) |
||||
|
||||
class DummyWallet(AbstractWallet): |
||||
|
||||
def __init__(self): |
||||
super(DummyWallet, self).__init__() |
||||
self.max_mix_depth = 5 |
||||
self.inject_addr_get_failure = False |
||||
|
||||
def get_utxos_by_mixdepth(self): |
||||
return t_utxos_by_mixdepth |
||||
|
||||
def select_utxos(self, mixdepth, amount): |
||||
if amount > self.get_balance_by_mixdepth()[mixdepth]: |
||||
raise Exception("Not enough funds") |
||||
return self.get_utxos_by_mixdepth()[mixdepth] |
||||
|
||||
def get_internal_addr(self, mixing_depth): |
||||
if self.inject_addr_get_failure: |
||||
raise Exception("address get failure") |
||||
return "mxeLuX8PP7qLkcM8uarHmdZyvP1b5e1Ynf" |
||||
|
||||
def sign_tx(self, tx, addrs): |
||||
print("Pretending to sign on addresses: " + str(addrs)) |
||||
return tx |
||||
|
||||
def get_key_from_addr(self, addr): |
||||
"""usable addresses: privkey all 1s, 2s, 3s, ... :""" |
||||
privs = [x*32 + "\x01" for x in [chr(y) for y in range(1,6)]] |
||||
addrs = {} |
||||
""" |
||||
mrcNu71ztWjAQA6ww9kHiW3zBWSQidHXTQ |
||||
n31WD8pkfAjg2APV78GnbDTdZb1QonBi5D |
||||
mmVEKH61BZbLbnVEmk9VmojreB4G4PmBPd |
||||
msxyyydNXTiBmt3SushXbH5Qh2ukBAThk3 |
||||
musGZczug3BAbqobmYherywCwL9REgNaNm |
||||
""" |
||||
for p in privs: |
||||
addrs[p] = bitcoin.privkey_to_address(p, False, magicbyte=0x6f) |
||||
for p, a in addrs.iteritems(): |
||||
if a == addr: |
||||
return binascii.hexlify(p) |
||||
raise ValueError("No such keypair") |
||||
|
||||
class DummyBlockchainInterface(BlockchainInterface): |
||||
def __init__(self): |
||||
self.fake_query_results = None |
||||
self.qusfail = False |
||||
|
||||
def sync_addresses(self, wallet): |
||||
pass |
||||
def sync_unspent(self, wallet): |
||||
pass |
||||
def add_tx_notify(self, |
||||
txd, |
||||
unconfirmfun, |
||||
confirmfun, |
||||
notifyaddr, |
||||
timeoutfun=None): |
||||
pass |
||||
|
||||
def pushtx(self, txhex): |
||||
print("pushing: " + str(txhex)) |
||||
return True |
||||
|
||||
def insert_fake_query_results(self, fqr): |
||||
self.fake_query_results = fqr |
||||
|
||||
def setQUSFail(self, state): |
||||
self.qusfail = state |
||||
|
||||
def query_utxo_set(self, txouts,includeconf=False): |
||||
if self.qusfail: |
||||
#simulate failure to find the utxo |
||||
return [None] |
||||
if self.fake_query_results: |
||||
result = [] |
||||
for x in self.fake_query_results: |
||||
for y in txouts: |
||||
if y == x['utxo']: |
||||
result.append(x) |
||||
return result |
||||
result = [] |
||||
#external maker utxos |
||||
known_outs = {"03243f4a659e278a1333f8308f6aaf32db4692ee7df0340202750fd6c09150f6:1": "03a2d1cbe977b1feaf8d0d5cc28c686859563d1520b28018be0c2661cf1ebe4857", |
||||
"498faa8b22534f3b443c6b0ce202f31e12f21668b4f0c7a005146808f250d4c3:0": "02b4b749d54e96b04066b0803e372a43d6ffa16e75a001ae0ed4b235674ab286be", |
||||
"3f3ea820d706e08ad8dc1d2c392c98facb1b067ae4c671043ae9461057bd2a3c:1": "023bcbafb4f68455e0d1d117c178b0e82a84e66414f0987453d78da034b299c3a9"} |
||||
#our wallet utxos, faked, for podle tests: utxos are doctored (leading 'f'), |
||||
#and the lists are (amt, age) |
||||
wallet_outs = {'f34b635ed8891f16c4ec5b8236ae86164783903e8e8bb47fa9ef2ca31f3c2d7a:0': [10000000, 2], |
||||
'f780d6e5e381bff01a3519997bb4fcba002493103a198fde334fd264f9835d75:1': [20000000, 6], |
||||
'fe574db96a4d43a99786b3ea653cda9e4388f377848f489332577e018380cff1:0': [50000000, 3], |
||||
'fd9711a2ef340750db21efb761f5f7d665d94b312332dc354e252c77e9c48349:0': [50000000, 6]} |
||||
|
||||
if includeconf and set(txouts).issubset(set(wallet_outs)): |
||||
#includeconf used as a trigger for a podle check; |
||||
#here we simulate a variety of amount/age returns |
||||
results = [] |
||||
for to in txouts: |
||||
results.append({'value': wallet_outs[to][0], |
||||
'confirms': wallet_outs[to][1]}) |
||||
return results |
||||
if txouts[0] in known_outs: |
||||
return [{'value': 200000000, |
||||
'address': bitcoin.pubkey_to_address(known_outs[txouts[0]], magicbyte=0x6f), |
||||
'confirms': 20}] |
||||
for t in txouts: |
||||
result_dict = {'value': 10000000000, |
||||
'address': "mrcNu71ztWjAQA6ww9kHiW3zBWSQidHXTQ"} |
||||
if includeconf: |
||||
result_dict['confirms'] = 20 |
||||
result.append(result_dict) |
||||
return result |
||||
|
||||
def estimate_fee_per_kb(self, N): |
||||
return 30000 |
||||
|
||||
def dummy_order_chooser(): |
||||
return t_chosen_orders |
||||
|
||||
def taker_finished(res, fromtx=False): |
||||
print("called taker finished callback") |
||||
|
||||
def dummy_filter_orderbook(orders_fees, cjamount): |
||||
print("calling dummy filter orderbook") |
||||
return True |
||||
|
||||
def get_taker(schedule=None, schedule_len=0, sign_method=None, on_finished=None, |
||||
filter_orders=None): |
||||
if not schedule: |
||||
schedule = ['a']*schedule_len #note, for taker.initalize() this will result in junk |
||||
print("Using schedule: " + str(schedule)) |
||||
on_finished_callback = on_finished if on_finished else taker_finished |
||||
filter_orders_callback = filter_orders if filter_orders else dummy_filter_orderbook |
||||
return Taker(DummyWallet(), schedule, |
||||
callbacks=[filter_orders_callback, None, on_finished_callback], |
||||
sign_method=sign_method) |
||||
|
||||
def test_filter_rejection(createcmtdata): |
||||
def filter_orders_reject(orders_feesl, cjamount): |
||||
print("calling filter orders rejection") |
||||
return False |
||||
taker = get_taker(filter_orders=filter_orders_reject) |
||||
taker.schedule = [(0, 20000000, 3, "mnsquzxrHXpFsZeL42qwbKdCP2y1esN3qw")] |
||||
res = taker.initialize(t_orderbook) |
||||
assert not res[0] |
||||
taker = get_taker(filter_orders=filter_orders_reject) |
||||
taker.schedule = [(0, 0, 3, "mnsquzxrHXpFsZeL42qwbKdCP2y1esN3qw")] |
||||
res = taker.initialize(t_orderbook) |
||||
assert not res[0] |
||||
|
||||
@pytest.mark.parametrize( |
||||
"failquery, external", |
||||
[ |
||||
(False, False), |
||||
(True, False), |
||||
(False, True), |
||||
]) |
||||
def test_make_commitment(createcmtdata, failquery, external): |
||||
def clean_up(): |
||||
jm_single().config.set("POLICY", "taker_utxo_age", old_taker_utxo_age) |
||||
jm_single().config.set("POLICY", "taker_utxo_amtpercent", old_taker_utxo_amtpercent) |
||||
set_commitment_file(old_commitment_file) |
||||
jm_single().bc_interface.setQUSFail(False) |
||||
os.remove('dummyext') |
||||
old_commitment_file = get_commitment_file() |
||||
with open('dummyext', 'wb') as f: |
||||
f.write(json.dumps(t_dummy_ext, indent=4)) |
||||
if external: |
||||
set_commitment_file('dummyext') |
||||
old_taker_utxo_age = jm_single().config.get("POLICY", "taker_utxo_age") |
||||
old_taker_utxo_amtpercent = jm_single().config.get("POLICY", "taker_utxo_amtpercent") |
||||
jm_single().config.set("POLICY", "taker_utxo_age", "5") |
||||
jm_single().config.set("POLICY", "taker_utxo_amtpercent", "20") |
||||
mixdepth = 0 |
||||
amount = 110000000 |
||||
taker = get_taker([(mixdepth, amount, 3, "mnsquzxrHXpFsZeL42qwbKdCP2y1esN3qw")]) |
||||
taker.wallet.unspent = {'f34b635ed8891f16c4ec5b8236ae86164783903e8e8bb47fa9ef2ca31f3c2d7a:0': |
||||
{'address': u'n31WD8pkfAjg2APV78GnbDTdZb1QonBi5D', |
||||
'value': 10000000}, |
||||
'f780d6e5e381bff01a3519997bb4fcba002493103a198fde334fd264f9835d75:1': |
||||
{'address': u'mmVEKH61BZbLbnVEmk9VmojreB4G4PmBPd', |
||||
'value': 20000000}, |
||||
'fe574db96a4d43a99786b3ea653cda9e4388f377848f489332577e018380cff1:0': |
||||
{'address': u'msxyyydNXTiBmt3SushXbH5Qh2ukBAThk3', |
||||
'value': 500000000}, |
||||
'fd9711a2ef340750db21efb761f5f7d665d94b312332dc354e252c77e9c48349:0': |
||||
{'address': u'musGZczug3BAbqobmYherywCwL9REgNaNm', |
||||
'value': 500000000}} |
||||
taker.cjamount = amount |
||||
taker.input_utxos = {'f34b635ed8891f16c4ec5b8236ae86164783903e8e8bb47fa9ef2ca31f3c2d7a:0': |
||||
{'address': u'n31WD8pkfAjg2APV78GnbDTdZb1QonBi5D', |
||||
'value': 10000000}} |
||||
if failquery: |
||||
jm_single().bc_interface.setQUSFail(True) |
||||
taker.make_commitment() |
||||
clean_up() |
||||
|
||||
def test_not_found_maker_utxos(createcmtdata): |
||||
taker = get_taker([(0, 20000000, 3, "mnsquzxrHXpFsZeL42qwbKdCP2y1esN3qw")]) |
||||
orderbook = copy.deepcopy(t_orderbook) |
||||
res = taker.initialize(orderbook) |
||||
taker.orderbook = copy.deepcopy(t_chosen_orders) #total_cjfee unaffected, all same |
||||
maker_response = copy.deepcopy(t_maker_response) |
||||
jm_single().bc_interface.setQUSFail(True) |
||||
res = taker.receive_utxos(maker_response) |
||||
assert not res[0] |
||||
assert res[1] == "Not enough counterparties responded to fill, giving up" |
||||
jm_single().bc_interface.setQUSFail(False) |
||||
|
||||
def test_auth_pub_not_found(createcmtdata): |
||||
taker = get_taker([(0, 20000000, 3, "mnsquzxrHXpFsZeL42qwbKdCP2y1esN3qw")]) |
||||
orderbook = copy.deepcopy(t_orderbook) |
||||
res = taker.initialize(orderbook) |
||||
taker.orderbook = copy.deepcopy(t_chosen_orders) #total_cjfee unaffected, all same |
||||
maker_response = copy.deepcopy(t_maker_response) |
||||
utxos = ["03243f4a659e278a1333f8308f6aaf32db4692ee7df0340202750fd6c09150f6:1", |
||||
"498faa8b22534f3b443c6b0ce202f31e12f21668b4f0c7a005146808f250d4c3:0", |
||||
"3f3ea820d706e08ad8dc1d2c392c98facb1b067ae4c671043ae9461057bd2a3c:1"] |
||||
fake_query_results = [{'value': 200000000, |
||||
'address': "blah", |
||||
'utxo': utxos[i], |
||||
'confirms': 20} for i in range(3)] |
||||
jm_single().bc_interface.insert_fake_query_results(fake_query_results) |
||||
res = taker.receive_utxos(maker_response) |
||||
assert not res[0] |
||||
assert res[1] == "Not enough counterparties responded to fill, giving up" |
||||
jm_single().bc_interface.insert_fake_query_results(None) |
||||
|
||||
@pytest.mark.parametrize( |
||||
"schedule, highfee, toomuchcoins, minmakers, notauthed, ignored, nocommit", |
||||
[ |
||||
([(0, 20000000, 3, "mnsquzxrHXpFsZeL42qwbKdCP2y1esN3qw")], False, False, |
||||
2, False, None, None), |
||||
([(0, 0, 3, "mnsquzxrHXpFsZeL42qwbKdCP2y1esN3qw")], False, False, |
||||
2, False, None, None), #sweep |
||||
#edge case triggers that don't fail |
||||
([(0, 0, 4, "mxeLuX8PP7qLkcM8uarHmdZyvP1b5e1Ynf")], False, False, |
||||
2, False, None, None), #sweep rounding error case |
||||
([(0, 199850001, 3, "mnsquzxrHXpFsZeL42qwbKdCP2y1esN3qw")], False, False, |
||||
2, False, None, None), #trigger sub dust change for taker |
||||
#edge case triggers that do fail |
||||
([(0, 199850000, 3, "mnsquzxrHXpFsZeL42qwbKdCP2y1esN3qw")], False, False, |
||||
2, False, None, None), #trigger negative change |
||||
([(0, 199599800, 3, "mnsquzxrHXpFsZeL42qwbKdCP2y1esN3qw")], False, False, |
||||
2, False, None, None), #trigger sub dust change for maker |
||||
([(0, 20000000, 3, "INTERNAL")], True, False, |
||||
2, False, None, None), #test high fee |
||||
([(0, 20000000, 3, "INTERNAL")], False, False, |
||||
7, False, None, None), #test not enough cp |
||||
([(0, 80000000, 3, "INTERNAL")], False, False, |
||||
2, False, None, "30000"), #test failed commit |
||||
([(0, 20000000, 3, "INTERNAL")], False, False, |
||||
2, True, None, None), #test unauthed response |
||||
([(0, 5000000000, 3, "mnsquzxrHXpFsZeL42qwbKdCP2y1esN3qw")], False, True, |
||||
2, False, None, None), #test too much coins |
||||
([(0, 0, 5, "mnsquzxrHXpFsZeL42qwbKdCP2y1esN3qw")], False, False, |
||||
2, False, ["J559UPUSLLjHJpaB", "J55z23xdjxJjC7er"], None), #test inadequate for sweep |
||||
]) |
||||
def test_taker_init(createcmtdata, schedule, highfee, toomuchcoins, minmakers, |
||||
notauthed, ignored, nocommit): |
||||
#these tests do not trigger utxo_retries |
||||
oldtakerutxoretries = jm_single().config.get("POLICY", "taker_utxo_retries") |
||||
oldtakerutxoamtpercent = jm_single().config.get("POLICY", "taker_utxo_amtpercent") |
||||
jm_single().config.set("POLICY", "taker_utxo_retries", "20") |
||||
def clean_up(): |
||||
jm_single().config.set("POLICY", "minimum_makers", oldminmakers) |
||||
jm_single().config.set("POLICY", "taker_utxo_retries", oldtakerutxoretries) |
||||
jm_single().config.set("POLICY", "taker_utxo_amtpercent", oldtakerutxoamtpercent) |
||||
oldminmakers = jm_single().config.get("POLICY", "minimum_makers") |
||||
jm_single().config.set("POLICY", "minimum_makers", str(minmakers)) |
||||
taker = get_taker(schedule) |
||||
orderbook = copy.deepcopy(t_orderbook) |
||||
if highfee: |
||||
for o in orderbook: |
||||
#trigger high-fee warning; but reset in next step |
||||
o['cjfee'] = '1.0' |
||||
if ignored: |
||||
taker.ignored_makers = ignored |
||||
if nocommit: |
||||
jm_single().config.set("POLICY", "taker_utxo_amtpercent", nocommit) |
||||
res = taker.initialize(orderbook) |
||||
if toomuchcoins or ignored: |
||||
assert not res[0] |
||||
return clean_up() |
||||
if nocommit: |
||||
print(str(res)) |
||||
assert not res[0] |
||||
return clean_up() |
||||
taker.orderbook = copy.deepcopy(t_chosen_orders) #total_cjfee unaffected, all same |
||||
maker_response = copy.deepcopy(t_maker_response) |
||||
if notauthed: |
||||
#Doctor one of the maker response data fields |
||||
maker_response["J559UPUSLLjHJpaB"][1] = "xx" #the auth pub |
||||
if schedule[0][1] == 199850000: |
||||
#triggers negative change |
||||
#makers offer 3000 txfee; we estimate ~ 147*10 + 2*34 + 10=1548 bytes |
||||
#times 30k = 46440, so we pay 43440, plus maker fees = 3*0.0002*200000000 |
||||
#roughly, gives required selected = amt + 163k, hence the above = |
||||
#2btc - 150k sats = 199850000 (tweaked because of aggressive coin selection) |
||||
#simulate the effect of a maker giving us a lot more utxos |
||||
taker.utxos["dummy_for_negative_change"] = ["a", "b", "c", "d", "e"] |
||||
with pytest.raises(ValueError) as e_info: |
||||
res = taker.receive_utxos(maker_response) |
||||
return clean_up() |
||||
if schedule[0][1] == 199850001: |
||||
#our own change is greater than zero but less than dust |
||||
#use the same edge case as for negative change, don't add dummy inputs |
||||
#(because we need tx creation to complete), but trigger case by |
||||
#bumping dust threshold |
||||
jm_single().BITCOIN_DUST_THRESHOLD = 10000 |
||||
res = taker.receive_utxos(maker_response) |
||||
#should have succeeded to build tx |
||||
assert res[0] |
||||
#change should be none |
||||
assert not taker.my_change_addr |
||||
return clean_up() |
||||
if schedule[0][1] == 199599800: |
||||
#need to force negative fees to make this feasible |
||||
for k, v in taker.orderbook.iteritems(): |
||||
v['cjfee'] = '-0.002' |
||||
# change_amount = (total_input - self.cjamount - |
||||
# self.orderbook[nick]['txfee'] + real_cjfee) |
||||
#suppose change amount is 1000 (sub dust), then solve for x; |
||||
#given that real_cjfee = -0.002*x |
||||
#change = 200000000 - x - 1000 - 0.002*x |
||||
#x*1.002 = 1999999000; x = 199599800 |
||||
res = taker.receive_utxos(maker_response) |
||||
assert not res[0] |
||||
assert res[1] == "Not enough counterparties responded to fill, giving up" |
||||
return clean_up() |
||||
if schedule[0][3] == "mxeLuX8PP7qLkcM8uarHmdZyvP1b5e1Ynf": |
||||
#to trigger rounding error for sweep (change non-zero), |
||||
#modify the total_input via the values in self.input_utxos; |
||||
#the amount to trigger a 2 satoshi change is found by trial-error. |
||||
#TODO note this test is not adequate, because the code is not; |
||||
#the code does not *DO* anything if a condition is unexpected. |
||||
taker.input_utxos = copy.deepcopy(t_utxos_by_mixdepth)[0] |
||||
for k,v in taker.input_utxos.iteritems(): |
||||
v["value"] = int(0.999805228 * v["value"]) |
||||
res = taker.receive_utxos(maker_response) |
||||
assert res[0] |
||||
return clean_up() |
||||
|
||||
res = taker.receive_utxos(maker_response) |
||||
if minmakers != 2: |
||||
assert not res[0] |
||||
assert res[1] == "Not enough counterparties responded to fill, giving up" |
||||
return clean_up() |
||||
|
||||
assert res[0] |
||||
#re-calling will trigger "finished" code, since schedule is "complete". |
||||
res = taker.initialize(orderbook) |
||||
assert not res[0] |
||||
|
||||
#some exception cases: no coinjoin address, no change address: |
||||
#donations not yet implemented: |
||||
taker.my_cj_addr = None |
||||
with pytest.raises(NotImplementedError) as e_info: |
||||
taker.prepare_my_bitcoin_data() |
||||
with pytest.raises(NotImplementedError) as e_info: |
||||
taker.sign_tx("a", "b", "c") |
||||
with pytest.raises(NotImplementedError) as e_info: |
||||
a = taker.coinjoin_address() |
||||
taker.wallet.inject_addr_get_failure = True |
||||
taker.my_cj_addr = "dummy" |
||||
assert not taker.prepare_my_bitcoin_data() |
||||
#clean up |
||||
return clean_up() |
||||
|
||||
@pytest.mark.parametrize( |
||||
"schedule_len", |
||||
[ |
||||
(7), |
||||
]) |
||||
def test_unconfirm_confirm(schedule_len): |
||||
"""These functions are: do-nothing by default (unconfirm, for Taker), |
||||
and merely update schedule index for confirm (useful for schedules/tumbles). |
||||
This tests that the on_finished callback correctly reports the fromtx |
||||
variable as "False" once the schedule is complete. |
||||
""" |
||||
test_unconfirm_confirm.txflag = True |
||||
def finished_for_confirms(res, fromtx=False): |
||||
assert res #confirmed should always send true |
||||
test_unconfirm_confirm.txflag = fromtx |
||||
|
||||
taker = get_taker(schedule_len=schedule_len, on_finished=finished_for_confirms) |
||||
taker.unconfirm_callback("a", "b") |
||||
for i in range(schedule_len-1): |
||||
taker.schedule_index += 1 |
||||
fromtx = taker.confirm_callback("a", "b", 1) |
||||
assert test_unconfirm_confirm.txflag |
||||
taker.schedule_index += 1 |
||||
fromtx = taker.confirm_callback("a", "b", 1) |
||||
assert not test_unconfirm_confirm.txflag |
||||
|
||||
@pytest.mark.parametrize( |
||||
"dummyaddr, signmethod, schedule", |
||||
[ |
||||
("mrcNu71ztWjAQA6ww9kHiW3zBWSQidHXTQ", None, |
||||
[(0, 20000000, 3, "mnsquzxrHXpFsZeL42qwbKdCP2y1esN3qw")]), |
||||
("mrcNu71ztWjAQA6ww9kHiW3zBWSQidHXTQ", "wallet", |
||||
[(0, 20000000, 3, "mnsquzxrHXpFsZeL42qwbKdCP2y1esN3qw")]), |
||||
]) |
||||
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) |
||||
|
||||
@pytest.mark.parametrize( |
||||
"schedule", |
||||
[ |
||||
([(0, 20000000, 3, "mnsquzxrHXpFsZeL42qwbKdCP2y1esN3qw")]), |
||||
]) |
||||
def test_auth_counterparty(schedule): |
||||
taker = get_taker(schedule=schedule) |
||||
first_maker_response = t_maker_response["J559UPUSLLjHJpaB"] |
||||
utxo, auth_pub, cjaddr, changeaddr, sig, maker_pub = first_maker_response |
||||
auth_pub_tweaked = auth_pub[:8] + auth_pub[6:8] + auth_pub[10:] |
||||
sig_tweaked = sig[:8] + sig[6:8] + sig[10:] |
||||
assert taker.auth_counterparty(sig, auth_pub, maker_pub) |
||||
assert not taker.auth_counterparty(sig, auth_pub_tweaked, maker_pub) |
||||
assert not taker.auth_counterparty(sig_tweaked, auth_pub, maker_pub) |
||||
|
||||
@pytest.fixture(scope="module") |
||||
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") |
||||
|
||||
|
||||
|
||||
|
||||
Loading…
Reference in new issue