21 changed files with 1611 additions and 161 deletions
@ -1,6 +1,6 @@ |
|||||||
from __future__ import print_function |
from __future__ import print_function |
||||||
|
|
||||||
from .support import (get_log, chunks, debug_silence, debug_dump_object, |
from .support import (get_log, chunks, debug_silence, debug_dump_object, |
||||||
joinmarket_alert, core_alert) |
joinmarket_alert, core_alert, get_password) |
||||||
from commands import * |
from commands import * |
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,152 @@ |
|||||||
|
[ |
||||||
|
[ |
||||||
|
"" |
||||||
|
], |
||||||
|
[ |
||||||
|
"x" |
||||||
|
], |
||||||
|
[ |
||||||
|
"37qgekLpCCHrQuSjvX3fs496FWTGsHFHizjJAs6NPcR47aefnnCWECAhHV6E3g4YN7u7Yuwod5Y" |
||||||
|
], |
||||||
|
[ |
||||||
|
"dzb7VV1Ui55BARxv7ATxAtCUeJsANKovDGWFVgpTbhq9gvPqP3yv" |
||||||
|
], |
||||||
|
[ |
||||||
|
"MuNu7ZAEDFiHthiunm7dPjwKqrVNCM3mAz6rP9zFveQu14YA8CxExSJTHcVP9DErn6u84E6Ej7S" |
||||||
|
], |
||||||
|
[ |
||||||
|
"rPpQpYknyNQ5AEHuY6H8ijJJrYc2nDKKk9jjmKEXsWzyAQcFGpDLU2Zvsmoi8JLR7hAwoy3RQWf" |
||||||
|
], |
||||||
|
[ |
||||||
|
"4Uc3FmN6NQ6zLBK5QQBXRBUREaaHwCZYsGCueHauuDmJpZKn6jkEskMB2Zi2CNgtb5r6epWEFfUJq" |
||||||
|
], |
||||||
|
[ |
||||||
|
"7aQgR5DFQ25vyXmqZAWmnVCjL3PkBcdVkBUpjrjMTcghHx3E8wb" |
||||||
|
], |
||||||
|
[ |
||||||
|
"17QpPprjeg69fW1DV8DcYYCKvWjYhXvWkov6MJ1iTTvMFj6weAqW7wybZeH57WTNxXVCRH4veVs" |
||||||
|
], |
||||||
|
[ |
||||||
|
"KxuACDviz8Xvpn1xAh9MfopySZNuyajYMZWz16Dv2mHHryznWUp3" |
||||||
|
], |
||||||
|
[ |
||||||
|
"7nK3GSmqdXJQtdohvGfJ7KsSmn3TmGqExug49583bDAL91pVSGq5xS9SHoAYL3Wv3ijKTit65th" |
||||||
|
], |
||||||
|
[ |
||||||
|
"cTivdBmq7bay3RFGEBBuNfMh2P1pDCgRYN2Wbxmgwr4ki3jNUL2va" |
||||||
|
], |
||||||
|
[ |
||||||
|
"gjMV4vjNjyMrna4fsAr8bWxAbwtmMUBXJS3zL4NJt5qjozpbQLmAfK1uA3CquSqsZQMpoD1g2nk" |
||||||
|
], |
||||||
|
[ |
||||||
|
"emXm1naBMoVzPjbk7xpeTVMFy4oDEe25UmoyGgKEB1gGWsK8kRGs" |
||||||
|
], |
||||||
|
[ |
||||||
|
"7VThQnNRj1o3Zyvc7XHPRrjDf8j2oivPTeDXnRPYWeYGE4pXeRJDZgf28ppti5hsHWXS2GSobdqyo" |
||||||
|
], |
||||||
|
[ |
||||||
|
"1G9u6oCVCPh2o8m3t55ACiYvG1y5BHewUkDSdiQarDcYXXhFHYdzMdYfUAhfxn5vNZBwpgUNpso" |
||||||
|
], |
||||||
|
[ |
||||||
|
"31QQ7ZMLkScDiB4VyZjuptr7AEc9j1SjstF7pRoLhHTGkW4Q2y9XELobQmhhWxeRvqcukGd1XCq" |
||||||
|
], |
||||||
|
[ |
||||||
|
"DHqKSnpxa8ZdQyH8keAhvLTrfkyBMQxqngcQA5N8LQ9KVt25kmGN" |
||||||
|
], |
||||||
|
[ |
||||||
|
"2LUHcJPbwLCy9GLH1qXmfmAwvadWw4bp4PCpDfduLqV17s6iDcy1imUwhQJhAoNoN1XNmweiJP4i" |
||||||
|
], |
||||||
|
[ |
||||||
|
"7USRzBXAnmck8fX9HmW7RAb4qt92VFX6soCnts9s74wxm4gguVhtG5of8fZGbNPJA83irHVY6bCos" |
||||||
|
], |
||||||
|
[ |
||||||
|
"1DGezo7BfVebZxAbNT3XGujdeHyNNBF3vnficYoTSp4PfK2QaML9bHzAMxke3wdKdHYWmsMTJVu" |
||||||
|
], |
||||||
|
[ |
||||||
|
"2D12DqDZKwCxxkzs1ZATJWvgJGhQ4cFi3WrizQ5zLAyhN5HxuAJ1yMYaJp8GuYsTLLxTAz6otCfb" |
||||||
|
], |
||||||
|
[ |
||||||
|
"8AFJzuTujXjw1Z6M3fWhQ1ujDW7zsV4ePeVjVo7D1egERqSW9nZ" |
||||||
|
], |
||||||
|
[ |
||||||
|
"163Q17qLbTCue8YY3AvjpUhotuaodLm2uqMhpYirsKjVqnxJRWTEoywMVY3NbBAHuhAJ2cF9GAZ" |
||||||
|
], |
||||||
|
[ |
||||||
|
"2MnmgiRH4eGLyLc9eAqStzk7dFgBjFtUCtu" |
||||||
|
], |
||||||
|
[ |
||||||
|
"461QQ2sYWxU7H2PV4oBwJGNch8XVTYYbZxU" |
||||||
|
], |
||||||
|
[ |
||||||
|
"2UCtv53VttmQYkVU4VMtXB31REvQg4ABzs41AEKZ8UcB7DAfVzdkV9JDErwGwyj5AUHLkmgZeobs" |
||||||
|
], |
||||||
|
[ |
||||||
|
"cSNjAsnhgtiFMi6MtfvgscMB2Cbhn2v1FUYfviJ1CdjfidvmeW6mn" |
||||||
|
], |
||||||
|
[ |
||||||
|
"gmsow2Y6EWAFDFE1CE4Hd3Tpu2BvfmBfG1SXsuRARbnt1WjkZnFh1qGTiptWWbjsq2Q6qvpgJVj" |
||||||
|
], |
||||||
|
[ |
||||||
|
"nksUKSkzS76v8EsSgozXGMoQFiCoCHzCVajFKAXqzK5on9ZJYVHMD5CKwgmX3S3c7M1U3xabUny" |
||||||
|
], |
||||||
|
[ |
||||||
|
"L3favK1UzFGgdzYBF2oBT5tbayCo4vtVBLJhg2iYuMeePxWG8SQc" |
||||||
|
], |
||||||
|
[ |
||||||
|
"7VxLxGGtYT6N99GdEfi6xz56xdQ8nP2dG1CavuXx7Rf2PrvNMTBNevjkfgs9JmkcGm6EXpj8ipyPZ" |
||||||
|
], |
||||||
|
[ |
||||||
|
"2mbZwFXF6cxShaCo2czTRB62WTx9LxhTtpP" |
||||||
|
], |
||||||
|
[ |
||||||
|
"dB7cwYdcPSgiyAwKWL3JwCVwSk6epU2txw" |
||||||
|
], |
||||||
|
[ |
||||||
|
"HPhFUhUAh8ZQQisH8QQWafAxtQYju3SFTX" |
||||||
|
], |
||||||
|
[ |
||||||
|
"4ctAH6AkHzq5ioiM1m9T3E2hiYEev5mTsB" |
||||||
|
], |
||||||
|
[ |
||||||
|
"Hn1uFi4dNexWrqARpjMqgT6cX1UsNPuV3cHdGg9ExyXw8HTKadbktRDtdeVmY3M1BxJStiL4vjJ" |
||||||
|
], |
||||||
|
[ |
||||||
|
"Sq3fDbvutABmnAHHExJDgPLQn44KnNC7UsXuT7KZecpaYDMU9Txs" |
||||||
|
], |
||||||
|
[ |
||||||
|
"6TqWyrqdgUEYDQU1aChMuFMMEimHX44qHFzCUgGfqxGgZNMUVWJ" |
||||||
|
], |
||||||
|
[ |
||||||
|
"giqJo7oWqFxNKWyrgcBxAVHXnjJ1t6cGoEffce5Y1y7u649Noj5wJ4mmiUAKEVVrYAGg2KPB3Y4" |
||||||
|
], |
||||||
|
[ |
||||||
|
"cNzHY5e8vcmM3QVJUcjCyiKMYfeYvyueq5qCMV3kqcySoLyGLYUK" |
||||||
|
], |
||||||
|
[ |
||||||
|
"37uTe568EYc9WLoHEd9jXEvUiWbq5LFLscNyqvAzLU5vBArUJA6eydkLmnMwJDjkL5kXc2VK7ig" |
||||||
|
], |
||||||
|
[ |
||||||
|
"EsYbG4tWWWY45G31nox838qNdzksbPySWc" |
||||||
|
], |
||||||
|
[ |
||||||
|
"nbuzhfwMoNzA3PaFnyLcRxE9bTJPDkjZ6Rf6Y6o2ckXZfzZzXBT" |
||||||
|
], |
||||||
|
[ |
||||||
|
"cQN9PoxZeCWK1x56xnz6QYAsvR11XAce3Ehp3gMUdfSQ53Y2mPzx" |
||||||
|
], |
||||||
|
[ |
||||||
|
"1Gm3N3rkef6iMbx4voBzaxtXcmmiMTqZPhcuAepRzYUJQW4qRpEnHvMojzof42hjFRf8PE2jPde" |
||||||
|
], |
||||||
|
[ |
||||||
|
"2TAq2tuN6x6m233bpT7yqdYQPELdTDJn1eU" |
||||||
|
], |
||||||
|
[ |
||||||
|
"ntEtnnGhqPii4joABvBtSEJG6BxjT2tUZqE8PcVYgk3RHpgxgHDCQxNbLJf7ardf1dDk2oCQ7Cf" |
||||||
|
], |
||||||
|
[ |
||||||
|
"Ky1YjoZNgQ196HJV3HpdkecfhRBmRZdMJk89Hi5KGfpfPwS2bUbfd" |
||||||
|
], |
||||||
|
[ |
||||||
|
"2A1q1YsMZowabbvta7kTy2Fd6qN4r5ZCeG3qLpvZBMzCixMUdkN2Y4dHB1wPsZAeVXUGD83MfRED" |
||||||
|
] |
||||||
|
] |
||||||
@ -0,0 +1,452 @@ |
|||||||
|
[ |
||||||
|
[ |
||||||
|
"1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62i", |
||||||
|
"65a16059864a2fdbc7c99a4723a8395bc6f188eb", |
||||||
|
{ |
||||||
|
"addrType": "pubkey", |
||||||
|
"isPrivkey": false, |
||||||
|
"isTestnet": false |
||||||
|
} |
||||||
|
], |
||||||
|
[ |
||||||
|
"3CMNFxN1oHBc4R1EpboAL5yzHGgE611Xou", |
||||||
|
"74f209f6ea907e2ea48f74fae05782ae8a665257", |
||||||
|
{ |
||||||
|
"addrType": "script", |
||||||
|
"isPrivkey": false, |
||||||
|
"isTestnet": false |
||||||
|
} |
||||||
|
], |
||||||
|
[ |
||||||
|
"mo9ncXisMeAoXwqcV5EWuyncbmCcQN4rVs", |
||||||
|
"53c0307d6851aa0ce7825ba883c6bd9ad242b486", |
||||||
|
{ |
||||||
|
"addrType": "pubkey", |
||||||
|
"isPrivkey": false, |
||||||
|
"isTestnet": true |
||||||
|
} |
||||||
|
], |
||||||
|
[ |
||||||
|
"2N2JD6wb56AfK4tfmM6PwdVmoYk2dCKf4Br", |
||||||
|
"6349a418fc4578d10a372b54b45c280cc8c4382f", |
||||||
|
{ |
||||||
|
"addrType": "script", |
||||||
|
"isPrivkey": false, |
||||||
|
"isTestnet": true |
||||||
|
} |
||||||
|
], |
||||||
|
[ |
||||||
|
"5Kd3NBUAdUnhyzenEwVLy9pBKxSwXvE9FMPyR4UKZvpe6E3AgLr", |
||||||
|
"eddbdc1168f1daeadbd3e44c1e3f8f5a284c2029f78ad26af98583a499de5b19", |
||||||
|
{ |
||||||
|
"isCompressed": false, |
||||||
|
"isPrivkey": true, |
||||||
|
"isTestnet": false |
||||||
|
} |
||||||
|
], |
||||||
|
[ |
||||||
|
"Kz6UJmQACJmLtaQj5A3JAge4kVTNQ8gbvXuwbmCj7bsaabudb3RD", |
||||||
|
"55c9bccb9ed68446d1b75273bbce89d7fe013a8acd1625514420fb2aca1a21c4", |
||||||
|
{ |
||||||
|
"isCompressed": true, |
||||||
|
"isPrivkey": true, |
||||||
|
"isTestnet": false |
||||||
|
} |
||||||
|
], |
||||||
|
[ |
||||||
|
"9213qJab2HNEpMpYNBa7wHGFKKbkDn24jpANDs2huN3yi4J11ko", |
||||||
|
"36cb93b9ab1bdabf7fb9f2c04f1b9cc879933530ae7842398eef5a63a56800c2", |
||||||
|
{ |
||||||
|
"isCompressed": false, |
||||||
|
"isPrivkey": true, |
||||||
|
"isTestnet": true |
||||||
|
} |
||||||
|
], |
||||||
|
[ |
||||||
|
"cTpB4YiyKiBcPxnefsDpbnDxFDffjqJob8wGCEDXxgQ7zQoMXJdH", |
||||||
|
"b9f4892c9e8282028fea1d2667c4dc5213564d41fc5783896a0d843fc15089f3", |
||||||
|
{ |
||||||
|
"isCompressed": true, |
||||||
|
"isPrivkey": true, |
||||||
|
"isTestnet": true |
||||||
|
} |
||||||
|
], |
||||||
|
[ |
||||||
|
"1Ax4gZtb7gAit2TivwejZHYtNNLT18PUXJ", |
||||||
|
"6d23156cbbdcc82a5a47eee4c2c7c583c18b6bf4", |
||||||
|
{ |
||||||
|
"addrType": "pubkey", |
||||||
|
"isPrivkey": false, |
||||||
|
"isTestnet": false |
||||||
|
} |
||||||
|
], |
||||||
|
[ |
||||||
|
"3QjYXhTkvuj8qPaXHTTWb5wjXhdsLAAWVy", |
||||||
|
"fcc5460dd6e2487c7d75b1963625da0e8f4c5975", |
||||||
|
{ |
||||||
|
"addrType": "script", |
||||||
|
"isPrivkey": false, |
||||||
|
"isTestnet": false |
||||||
|
} |
||||||
|
], |
||||||
|
[ |
||||||
|
"n3ZddxzLvAY9o7184TB4c6FJasAybsw4HZ", |
||||||
|
"f1d470f9b02370fdec2e6b708b08ac431bf7a5f7", |
||||||
|
{ |
||||||
|
"addrType": "pubkey", |
||||||
|
"isPrivkey": false, |
||||||
|
"isTestnet": true |
||||||
|
} |
||||||
|
], |
||||||
|
[ |
||||||
|
"2NBFNJTktNa7GZusGbDbGKRZTxdK9VVez3n", |
||||||
|
"c579342c2c4c9220205e2cdc285617040c924a0a", |
||||||
|
{ |
||||||
|
"addrType": "script", |
||||||
|
"isPrivkey": false, |
||||||
|
"isTestnet": true |
||||||
|
} |
||||||
|
], |
||||||
|
[ |
||||||
|
"5K494XZwps2bGyeL71pWid4noiSNA2cfCibrvRWqcHSptoFn7rc", |
||||||
|
"a326b95ebae30164217d7a7f57d72ab2b54e3be64928a19da0210b9568d4015e", |
||||||
|
{ |
||||||
|
"isCompressed": false, |
||||||
|
"isPrivkey": true, |
||||||
|
"isTestnet": false |
||||||
|
} |
||||||
|
], |
||||||
|
[ |
||||||
|
"L1RrrnXkcKut5DEMwtDthjwRcTTwED36thyL1DebVrKuwvohjMNi", |
||||||
|
"7d998b45c219a1e38e99e7cbd312ef67f77a455a9b50c730c27f02c6f730dfb4", |
||||||
|
{ |
||||||
|
"isCompressed": true, |
||||||
|
"isPrivkey": true, |
||||||
|
"isTestnet": false |
||||||
|
} |
||||||
|
], |
||||||
|
[ |
||||||
|
"93DVKyFYwSN6wEo3E2fCrFPUp17FtrtNi2Lf7n4G3garFb16CRj", |
||||||
|
"d6bca256b5abc5602ec2e1c121a08b0da2556587430bcf7e1898af2224885203", |
||||||
|
{ |
||||||
|
"isCompressed": false, |
||||||
|
"isPrivkey": true, |
||||||
|
"isTestnet": true |
||||||
|
} |
||||||
|
], |
||||||
|
[ |
||||||
|
"cTDVKtMGVYWTHCb1AFjmVbEbWjvKpKqKgMaR3QJxToMSQAhmCeTN", |
||||||
|
"a81ca4e8f90181ec4b61b6a7eb998af17b2cb04de8a03b504b9e34c4c61db7d9", |
||||||
|
{ |
||||||
|
"isCompressed": true, |
||||||
|
"isPrivkey": true, |
||||||
|
"isTestnet": true |
||||||
|
} |
||||||
|
], |
||||||
|
[ |
||||||
|
"1C5bSj1iEGUgSTbziymG7Cn18ENQuT36vv", |
||||||
|
"7987ccaa53d02c8873487ef919677cd3db7a6912", |
||||||
|
{ |
||||||
|
"addrType": "pubkey", |
||||||
|
"isPrivkey": false, |
||||||
|
"isTestnet": false |
||||||
|
} |
||||||
|
], |
||||||
|
[ |
||||||
|
"3AnNxabYGoTxYiTEZwFEnerUoeFXK2Zoks", |
||||||
|
"63bcc565f9e68ee0189dd5cc67f1b0e5f02f45cb", |
||||||
|
{ |
||||||
|
"addrType": "script", |
||||||
|
"isPrivkey": false, |
||||||
|
"isTestnet": false |
||||||
|
} |
||||||
|
], |
||||||
|
[ |
||||||
|
"n3LnJXCqbPjghuVs8ph9CYsAe4Sh4j97wk", |
||||||
|
"ef66444b5b17f14e8fae6e7e19b045a78c54fd79", |
||||||
|
{ |
||||||
|
"addrType": "pubkey", |
||||||
|
"isPrivkey": false, |
||||||
|
"isTestnet": true |
||||||
|
} |
||||||
|
], |
||||||
|
[ |
||||||
|
"2NB72XtkjpnATMggui83aEtPawyyKvnbX2o", |
||||||
|
"c3e55fceceaa4391ed2a9677f4a4d34eacd021a0", |
||||||
|
{ |
||||||
|
"addrType": "script", |
||||||
|
"isPrivkey": false, |
||||||
|
"isTestnet": true |
||||||
|
} |
||||||
|
], |
||||||
|
[ |
||||||
|
"5KaBW9vNtWNhc3ZEDyNCiXLPdVPHCikRxSBWwV9NrpLLa4LsXi9", |
||||||
|
"e75d936d56377f432f404aabb406601f892fd49da90eb6ac558a733c93b47252", |
||||||
|
{ |
||||||
|
"isCompressed": false, |
||||||
|
"isPrivkey": true, |
||||||
|
"isTestnet": false |
||||||
|
} |
||||||
|
], |
||||||
|
[ |
||||||
|
"L1axzbSyynNYA8mCAhzxkipKkfHtAXYF4YQnhSKcLV8YXA874fgT", |
||||||
|
"8248bd0375f2f75d7e274ae544fb920f51784480866b102384190b1addfbaa5c", |
||||||
|
{ |
||||||
|
"isCompressed": true, |
||||||
|
"isPrivkey": true, |
||||||
|
"isTestnet": false |
||||||
|
} |
||||||
|
], |
||||||
|
[ |
||||||
|
"927CnUkUbasYtDwYwVn2j8GdTuACNnKkjZ1rpZd2yBB1CLcnXpo", |
||||||
|
"44c4f6a096eac5238291a94cc24c01e3b19b8d8cef72874a079e00a242237a52", |
||||||
|
{ |
||||||
|
"isCompressed": false, |
||||||
|
"isPrivkey": true, |
||||||
|
"isTestnet": true |
||||||
|
} |
||||||
|
], |
||||||
|
[ |
||||||
|
"cUcfCMRjiQf85YMzzQEk9d1s5A4K7xL5SmBCLrezqXFuTVefyhY7", |
||||||
|
"d1de707020a9059d6d3abaf85e17967c6555151143db13dbb06db78df0f15c69", |
||||||
|
{ |
||||||
|
"isCompressed": true, |
||||||
|
"isPrivkey": true, |
||||||
|
"isTestnet": true |
||||||
|
} |
||||||
|
], |
||||||
|
[ |
||||||
|
"1Gqk4Tv79P91Cc1STQtU3s1W6277M2CVWu", |
||||||
|
"adc1cc2081a27206fae25792f28bbc55b831549d", |
||||||
|
{ |
||||||
|
"addrType": "pubkey", |
||||||
|
"isPrivkey": false, |
||||||
|
"isTestnet": false |
||||||
|
} |
||||||
|
], |
||||||
|
[ |
||||||
|
"33vt8ViH5jsr115AGkW6cEmEz9MpvJSwDk", |
||||||
|
"188f91a931947eddd7432d6e614387e32b244709", |
||||||
|
{ |
||||||
|
"addrType": "script", |
||||||
|
"isPrivkey": false, |
||||||
|
"isTestnet": false |
||||||
|
} |
||||||
|
], |
||||||
|
[ |
||||||
|
"mhaMcBxNh5cqXm4aTQ6EcVbKtfL6LGyK2H", |
||||||
|
"1694f5bc1a7295b600f40018a618a6ea48eeb498", |
||||||
|
{ |
||||||
|
"addrType": "pubkey", |
||||||
|
"isPrivkey": false, |
||||||
|
"isTestnet": true |
||||||
|
} |
||||||
|
], |
||||||
|
[ |
||||||
|
"2MxgPqX1iThW3oZVk9KoFcE5M4JpiETssVN", |
||||||
|
"3b9b3fd7a50d4f08d1a5b0f62f644fa7115ae2f3", |
||||||
|
{ |
||||||
|
"addrType": "script", |
||||||
|
"isPrivkey": false, |
||||||
|
"isTestnet": true |
||||||
|
} |
||||||
|
], |
||||||
|
[ |
||||||
|
"5HtH6GdcwCJA4ggWEL1B3jzBBUB8HPiBi9SBc5h9i4Wk4PSeApR", |
||||||
|
"091035445ef105fa1bb125eccfb1882f3fe69592265956ade751fd095033d8d0", |
||||||
|
{ |
||||||
|
"isCompressed": false, |
||||||
|
"isPrivkey": true, |
||||||
|
"isTestnet": false |
||||||
|
} |
||||||
|
], |
||||||
|
[ |
||||||
|
"L2xSYmMeVo3Zek3ZTsv9xUrXVAmrWxJ8Ua4cw8pkfbQhcEFhkXT8", |
||||||
|
"ab2b4bcdfc91d34dee0ae2a8c6b6668dadaeb3a88b9859743156f462325187af", |
||||||
|
{ |
||||||
|
"isCompressed": true, |
||||||
|
"isPrivkey": true, |
||||||
|
"isTestnet": false |
||||||
|
} |
||||||
|
], |
||||||
|
[ |
||||||
|
"92xFEve1Z9N8Z641KQQS7ByCSb8kGjsDzw6fAmjHN1LZGKQXyMq", |
||||||
|
"b4204389cef18bbe2b353623cbf93e8678fbc92a475b664ae98ed594e6cf0856", |
||||||
|
{ |
||||||
|
"isCompressed": false, |
||||||
|
"isPrivkey": true, |
||||||
|
"isTestnet": true |
||||||
|
} |
||||||
|
], |
||||||
|
[ |
||||||
|
"cVM65tdYu1YK37tNoAyGoJTR13VBYFva1vg9FLuPAsJijGvG6NEA", |
||||||
|
"e7b230133f1b5489843260236b06edca25f66adb1be455fbd38d4010d48faeef", |
||||||
|
{ |
||||||
|
"isCompressed": true, |
||||||
|
"isPrivkey": true, |
||||||
|
"isTestnet": true |
||||||
|
} |
||||||
|
], |
||||||
|
[ |
||||||
|
"1JwMWBVLtiqtscbaRHai4pqHokhFCbtoB4", |
||||||
|
"c4c1b72491ede1eedaca00618407ee0b772cad0d", |
||||||
|
{ |
||||||
|
"addrType": "pubkey", |
||||||
|
"isPrivkey": false, |
||||||
|
"isTestnet": false |
||||||
|
} |
||||||
|
], |
||||||
|
[ |
||||||
|
"3QCzvfL4ZRvmJFiWWBVwxfdaNBT8EtxB5y", |
||||||
|
"f6fe69bcb548a829cce4c57bf6fff8af3a5981f9", |
||||||
|
{ |
||||||
|
"addrType": "script", |
||||||
|
"isPrivkey": false, |
||||||
|
"isTestnet": false |
||||||
|
} |
||||||
|
], |
||||||
|
[ |
||||||
|
"mizXiucXRCsEriQCHUkCqef9ph9qtPbZZ6", |
||||||
|
"261f83568a098a8638844bd7aeca039d5f2352c0", |
||||||
|
{ |
||||||
|
"addrType": "pubkey", |
||||||
|
"isPrivkey": false, |
||||||
|
"isTestnet": true |
||||||
|
} |
||||||
|
], |
||||||
|
[ |
||||||
|
"2NEWDzHWwY5ZZp8CQWbB7ouNMLqCia6YRda", |
||||||
|
"e930e1834a4d234702773951d627cce82fbb5d2e", |
||||||
|
{ |
||||||
|
"addrType": "script", |
||||||
|
"isPrivkey": false, |
||||||
|
"isTestnet": true |
||||||
|
} |
||||||
|
], |
||||||
|
[ |
||||||
|
"5KQmDryMNDcisTzRp3zEq9e4awRmJrEVU1j5vFRTKpRNYPqYrMg", |
||||||
|
"d1fab7ab7385ad26872237f1eb9789aa25cc986bacc695e07ac571d6cdac8bc0", |
||||||
|
{ |
||||||
|
"isCompressed": false, |
||||||
|
"isPrivkey": true, |
||||||
|
"isTestnet": false |
||||||
|
} |
||||||
|
], |
||||||
|
[ |
||||||
|
"L39Fy7AC2Hhj95gh3Yb2AU5YHh1mQSAHgpNixvm27poizcJyLtUi", |
||||||
|
"b0bbede33ef254e8376aceb1510253fc3550efd0fcf84dcd0c9998b288f166b3", |
||||||
|
{ |
||||||
|
"isCompressed": true, |
||||||
|
"isPrivkey": true, |
||||||
|
"isTestnet": false |
||||||
|
} |
||||||
|
], |
||||||
|
[ |
||||||
|
"91cTVUcgydqyZLgaANpf1fvL55FH53QMm4BsnCADVNYuWuqdVys", |
||||||
|
"037f4192c630f399d9271e26c575269b1d15be553ea1a7217f0cb8513cef41cb", |
||||||
|
{ |
||||||
|
"isCompressed": false, |
||||||
|
"isPrivkey": true, |
||||||
|
"isTestnet": true |
||||||
|
} |
||||||
|
], |
||||||
|
[ |
||||||
|
"cQspfSzsgLeiJGB2u8vrAiWpCU4MxUT6JseWo2SjXy4Qbzn2fwDw", |
||||||
|
"6251e205e8ad508bab5596bee086ef16cd4b239e0cc0c5d7c4e6035441e7d5de", |
||||||
|
{ |
||||||
|
"isCompressed": true, |
||||||
|
"isPrivkey": true, |
||||||
|
"isTestnet": true |
||||||
|
} |
||||||
|
], |
||||||
|
[ |
||||||
|
"19dcawoKcZdQz365WpXWMhX6QCUpR9SY4r", |
||||||
|
"5eadaf9bb7121f0f192561a5a62f5e5f54210292", |
||||||
|
{ |
||||||
|
"addrType": "pubkey", |
||||||
|
"isPrivkey": false, |
||||||
|
"isTestnet": false |
||||||
|
} |
||||||
|
], |
||||||
|
[ |
||||||
|
"37Sp6Rv3y4kVd1nQ1JV5pfqXccHNyZm1x3", |
||||||
|
"3f210e7277c899c3a155cc1c90f4106cbddeec6e", |
||||||
|
{ |
||||||
|
"addrType": "script", |
||||||
|
"isPrivkey": false, |
||||||
|
"isTestnet": false |
||||||
|
} |
||||||
|
], |
||||||
|
[ |
||||||
|
"myoqcgYiehufrsnnkqdqbp69dddVDMopJu", |
||||||
|
"c8a3c2a09a298592c3e180f02487cd91ba3400b5", |
||||||
|
{ |
||||||
|
"addrType": "pubkey", |
||||||
|
"isPrivkey": false, |
||||||
|
"isTestnet": true |
||||||
|
} |
||||||
|
], |
||||||
|
[ |
||||||
|
"2N7FuwuUuoTBrDFdrAZ9KxBmtqMLxce9i1C", |
||||||
|
"99b31df7c9068d1481b596578ddbb4d3bd90baeb", |
||||||
|
{ |
||||||
|
"addrType": "script", |
||||||
|
"isPrivkey": false, |
||||||
|
"isTestnet": true |
||||||
|
} |
||||||
|
], |
||||||
|
[ |
||||||
|
"5KL6zEaMtPRXZKo1bbMq7JDjjo1bJuQcsgL33je3oY8uSJCR5b4", |
||||||
|
"c7666842503db6dc6ea061f092cfb9c388448629a6fe868d068c42a488b478ae", |
||||||
|
{ |
||||||
|
"isCompressed": false, |
||||||
|
"isPrivkey": true, |
||||||
|
"isTestnet": false |
||||||
|
} |
||||||
|
], |
||||||
|
[ |
||||||
|
"KwV9KAfwbwt51veZWNscRTeZs9CKpojyu1MsPnaKTF5kz69H1UN2", |
||||||
|
"07f0803fc5399e773555ab1e8939907e9badacc17ca129e67a2f5f2ff84351dd", |
||||||
|
{ |
||||||
|
"isCompressed": true, |
||||||
|
"isPrivkey": true, |
||||||
|
"isTestnet": false |
||||||
|
} |
||||||
|
], |
||||||
|
[ |
||||||
|
"93N87D6uxSBzwXvpokpzg8FFmfQPmvX4xHoWQe3pLdYpbiwT5YV", |
||||||
|
"ea577acfb5d1d14d3b7b195c321566f12f87d2b77ea3a53f68df7ebf8604a801", |
||||||
|
{ |
||||||
|
"isCompressed": false, |
||||||
|
"isPrivkey": true, |
||||||
|
"isTestnet": true |
||||||
|
} |
||||||
|
], |
||||||
|
[ |
||||||
|
"cMxXusSihaX58wpJ3tNuuUcZEQGt6DKJ1wEpxys88FFaQCYjku9h", |
||||||
|
"0b3b34f0958d8a268193a9814da92c3e8b58b4a4378a542863e34ac289cd830c", |
||||||
|
{ |
||||||
|
"isCompressed": true, |
||||||
|
"isPrivkey": true, |
||||||
|
"isTestnet": true |
||||||
|
} |
||||||
|
], |
||||||
|
[ |
||||||
|
"13p1ijLwsnrcuyqcTvJXkq2ASdXqcnEBLE", |
||||||
|
"1ed467017f043e91ed4c44b4e8dd674db211c4e6", |
||||||
|
{ |
||||||
|
"addrType": "pubkey", |
||||||
|
"isPrivkey": false, |
||||||
|
"isTestnet": false |
||||||
|
} |
||||||
|
], |
||||||
|
[ |
||||||
|
"3ALJH9Y951VCGcVZYAdpA3KchoP9McEj1G", |
||||||
|
"5ece0cadddc415b1980f001785947120acdb36fc", |
||||||
|
{ |
||||||
|
"addrType": "script", |
||||||
|
"isPrivkey": false, |
||||||
|
"isTestnet": false |
||||||
|
} |
||||||
|
] |
||||||
|
] |
||||||
@ -0,0 +1,42 @@ |
|||||||
|
from jmclient.configure import validate_address, load_program_config |
||||||
|
from jmclient import jm_single |
||||||
|
import json |
||||||
|
import pytest |
||||||
|
|
||||||
|
|
||||||
|
def test_non_addresses(setup_addresses): |
||||||
|
#could flesh this out with other examples |
||||||
|
res, msg = validate_address(2) |
||||||
|
assert res == False, "Incorrectly accepted number" |
||||||
|
|
||||||
|
def test_b58_invalid_addresses(setup_addresses): |
||||||
|
#none of these are valid as any kind of key or address |
||||||
|
with open("base58_keys_invalid.json", "r") as f: |
||||||
|
json_data = f.read() |
||||||
|
invalid_key_list = json.loads(json_data) |
||||||
|
for k in invalid_key_list: |
||||||
|
bad_key = k[0] |
||||||
|
res, message = validate_address(bad_key) |
||||||
|
assert res == False, "Incorrectly validated address: " + bad_key + " with message: " + message |
||||||
|
|
||||||
|
|
||||||
|
def test_b58_valid_addresses(): |
||||||
|
with open("base58_keys_valid.json", "r") as f: |
||||||
|
json_data = f.read() |
||||||
|
valid_keys_list = json.loads(json_data) |
||||||
|
for a in valid_keys_list: |
||||||
|
addr, pubkey, prop_dict = a |
||||||
|
if not prop_dict["isPrivkey"]: |
||||||
|
if prop_dict["isTestnet"]: |
||||||
|
jm_single().config.set("BLOCKCHAIN", "network", "testnet") |
||||||
|
else: |
||||||
|
jm_single().config.set("BLOCKCHAIN", "network", "mainnet") |
||||||
|
#if using py.test -s ; sanity check to see what's actually being tested |
||||||
|
print 'testing this address: ' + addr |
||||||
|
res, message = validate_address(addr) |
||||||
|
assert res == True, "Incorrectly failed to validate address: " + addr + " with message: " + message |
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(scope="module") |
||||||
|
def setup_addresses(): |
||||||
|
load_program_config() |
||||||
@ -0,0 +1,61 @@ |
|||||||
|
#! /usr/bin/env python |
||||||
|
from __future__ import absolute_import |
||||||
|
'''test schedule module.''' |
||||||
|
|
||||||
|
import pytest |
||||||
|
from jmclient import (load_program_config, jm_single, get_irc_mchannels, |
||||||
|
BTC_P2PK_VBYTE, BTC_P2SH_VBYTE, check_utxo_blacklist, |
||||||
|
validate_address) |
||||||
|
from jmclient.configure import (get_config_irc_channel, get_p2sh_vbyte, |
||||||
|
get_p2pk_vbyte, get_blockchain_interface_instance) |
||||||
|
import jmbitcoin as bitcoin |
||||||
|
import copy |
||||||
|
import os |
||||||
|
|
||||||
|
|
||||||
|
def test_config_get_irc_channel(): |
||||||
|
load_program_config() |
||||||
|
channel = "dummy" |
||||||
|
assert get_config_irc_channel(channel) == "#dummy-test" |
||||||
|
jm_single().config.set("BLOCKCHAIN", "network", "mainnet") |
||||||
|
assert get_config_irc_channel(channel) == "#dummy" |
||||||
|
get_irc_mchannels() |
||||||
|
load_program_config() |
||||||
|
|
||||||
|
def test_net_byte(): |
||||||
|
load_program_config() |
||||||
|
assert get_p2pk_vbyte() == 0x6f |
||||||
|
assert get_p2sh_vbyte() == 196 |
||||||
|
|
||||||
|
def test_check_blacklist(): |
||||||
|
load_program_config() |
||||||
|
jm_single().nickname = "fortestnick" |
||||||
|
fn = "blacklist" + "_" + jm_single().nickname |
||||||
|
if os.path.exists(fn): |
||||||
|
os.remove(fn) |
||||||
|
assert check_utxo_blacklist("aa"*32, False) |
||||||
|
with open(fn, "wb") as f: |
||||||
|
f.write("aa"*32 + "\n") |
||||||
|
assert not check_utxo_blacklist("aa"*32, False) |
||||||
|
assert check_utxo_blacklist("bb"*32, False) |
||||||
|
assert check_utxo_blacklist("bb"*32, True) |
||||||
|
assert not check_utxo_blacklist("bb"*32, False) |
||||||
|
assert not check_utxo_blacklist("bb"*32, True) |
||||||
|
|
||||||
|
def test_blockchain_sources(): |
||||||
|
load_program_config() |
||||||
|
for src in ["blockr", "electrum", "dummy"]: |
||||||
|
jm_single().config.set("BLOCKCHAIN", "blockchain_source", src) |
||||||
|
if src=="electrum": |
||||||
|
jm_single().config.set("BLOCKCHAIN", "network", "mainnet") |
||||||
|
if src == "dummy": |
||||||
|
with pytest.raises(ValueError) as e_info: |
||||||
|
get_blockchain_interface_instance(jm_single().config) |
||||||
|
else: |
||||||
|
get_blockchain_interface_instance(jm_single().config) |
||||||
|
load_program_config() |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -0,0 +1,237 @@ |
|||||||
|
#! /usr/bin/env python |
||||||
|
from __future__ import print_function |
||||||
|
'''Tests of Proof of discrete log equivalence commitments.''' |
||||||
|
import os |
||||||
|
import jmbitcoin as bitcoin |
||||||
|
import binascii |
||||||
|
import json |
||||||
|
import pytest |
||||||
|
import copy |
||||||
|
import subprocess |
||||||
|
import signal |
||||||
|
from commontest import local_command, make_wallets |
||||||
|
import time |
||||||
|
from pprint import pformat |
||||||
|
from jmclient import (load_program_config, get_log, jm_single, generate_podle, |
||||||
|
generate_podle_error_string, set_commitment_file, |
||||||
|
get_commitment_file, PoDLE, get_podle_commitments, |
||||||
|
add_external_commitments, update_commitments) |
||||||
|
from jmclient.podle import verify_all_NUMS, verify_podle, PoDLEError |
||||||
|
log = get_log() |
||||||
|
|
||||||
|
def test_commitments_empty(setup_podle): |
||||||
|
"""Ensure that empty commitments file |
||||||
|
results in {} |
||||||
|
""" |
||||||
|
assert get_podle_commitments() == ([], {}) |
||||||
|
|
||||||
|
def test_commitment_retries(setup_podle): |
||||||
|
"""Assumes no external commitments available. |
||||||
|
Generate pretend priv/utxo pairs and check that they can be used |
||||||
|
taker_utxo_retries times. |
||||||
|
""" |
||||||
|
allowed = jm_single().config.getint("POLICY", "taker_utxo_retries") |
||||||
|
#make some pretend commitments |
||||||
|
dummy_priv_utxo_pairs = [(bitcoin.sha256(os.urandom(10)), |
||||||
|
bitcoin.sha256(os.urandom(10))+":0") for _ in range(10)] |
||||||
|
#test a single commitment request of all 10 |
||||||
|
for x in dummy_priv_utxo_pairs: |
||||||
|
p = generate_podle([x], allowed) |
||||||
|
assert p |
||||||
|
#At this point slot 0 has been taken by all 10. |
||||||
|
for i in range(allowed-1): |
||||||
|
p = generate_podle(dummy_priv_utxo_pairs[:1], allowed) |
||||||
|
assert p |
||||||
|
p = generate_podle(dummy_priv_utxo_pairs[:1], allowed) |
||||||
|
assert p is None |
||||||
|
|
||||||
|
def generate_single_podle_sig(priv, i): |
||||||
|
"""Make a podle entry for key priv at index i, using a dummy utxo value. |
||||||
|
This calls the underlying 'raw' code based on the class PoDLE, not the |
||||||
|
library 'generate_podle' which intelligently searches and updates commitments. |
||||||
|
""" |
||||||
|
dummy_utxo = bitcoin.sha256(priv) + ":3" |
||||||
|
podle = PoDLE(dummy_utxo, binascii.hexlify(priv)) |
||||||
|
r = podle.generate_podle(i) |
||||||
|
return (r['P'], r['P2'], r['sig'], |
||||||
|
r['e'], r['commit']) |
||||||
|
|
||||||
|
def test_rand_commitments(setup_podle): |
||||||
|
for i in range(20): |
||||||
|
priv = os.urandom(32) |
||||||
|
Pser, P2ser, s, e, commitment = generate_single_podle_sig(priv, 1 + i%5) |
||||||
|
assert verify_podle(Pser, P2ser, s, e, commitment) |
||||||
|
#tweak commitments to verify failure |
||||||
|
tweaked = [x[::-1] for x in [Pser, P2ser, s, e, commitment]] |
||||||
|
for i in range(5): |
||||||
|
#Check failure on garbling of each parameter |
||||||
|
y = [Pser, P2ser, s, e, commitment] |
||||||
|
y[i] = tweaked[i] |
||||||
|
fail = False |
||||||
|
try: |
||||||
|
fail = verify_podle(*y) |
||||||
|
except: |
||||||
|
pass |
||||||
|
finally: |
||||||
|
assert not fail |
||||||
|
|
||||||
|
def test_nums_verify(setup_podle): |
||||||
|
"""Check that the NUMS precomputed values are |
||||||
|
valid according to the code; assertion check |
||||||
|
implicit. |
||||||
|
""" |
||||||
|
verify_all_NUMS(True) |
||||||
|
|
||||||
|
def test_external_commitments(setup_podle): |
||||||
|
"""Add this generated commitment to the external list |
||||||
|
{txid:N:{'P':pubkey, 'reveal':{1:{'P2':P2,'s':s,'e':e}, 2:{..},..}}} |
||||||
|
Note we do this *after* the sendpayment test so that the external |
||||||
|
commitments will not erroneously used (they are fake). |
||||||
|
""" |
||||||
|
#ensure the file exists even if empty |
||||||
|
update_commitments() |
||||||
|
ecs = {} |
||||||
|
tries = jm_single().config.getint("POLICY","taker_utxo_retries") |
||||||
|
for i in range(10): |
||||||
|
priv = os.urandom(32) |
||||||
|
dummy_utxo = bitcoin.sha256(priv)+":2" |
||||||
|
ecs[dummy_utxo] = {} |
||||||
|
ecs[dummy_utxo]['reveal']={} |
||||||
|
for j in range(tries): |
||||||
|
P, P2, s, e, commit = generate_single_podle_sig(priv, j) |
||||||
|
if 'P' not in ecs[dummy_utxo]: |
||||||
|
ecs[dummy_utxo]['P']=P |
||||||
|
ecs[dummy_utxo]['reveal'][j] = {'P2':P2, 's':s, 'e':e} |
||||||
|
add_external_commitments(ecs) |
||||||
|
used, external = get_podle_commitments() |
||||||
|
for u in external: |
||||||
|
assert external[u]['P'] == ecs[u]['P'] |
||||||
|
for i in range(tries): |
||||||
|
for x in ['P2', 's', 'e']: |
||||||
|
assert external[u]['reveal'][str(i)][x] == ecs[u]['reveal'][i][x] |
||||||
|
|
||||||
|
#add a dummy used commitment, then try again |
||||||
|
update_commitments(commitment="ab"*32) |
||||||
|
ecs = {} |
||||||
|
known_commits = [] |
||||||
|
known_utxos = [] |
||||||
|
tries = 3 |
||||||
|
for i in range(1, 6): |
||||||
|
u = binascii.hexlify(chr(i)*32) |
||||||
|
known_utxos.append(u) |
||||||
|
priv = chr(i)*32+"\x01" |
||||||
|
ecs[u] = {} |
||||||
|
ecs[u]['reveal']={} |
||||||
|
for j in range(tries): |
||||||
|
P, P2, s, e, commit = generate_single_podle_sig(priv, j) |
||||||
|
known_commits.append(commit) |
||||||
|
if 'P' not in ecs[u]: |
||||||
|
ecs[u]['P'] = P |
||||||
|
ecs[u]['reveal'][j] = {'P2':P2, 's':s, 'e':e} |
||||||
|
add_external_commitments(ecs) |
||||||
|
#simulate most of those external being already used |
||||||
|
for c in known_commits[:-1]: |
||||||
|
update_commitments(commitment=c) |
||||||
|
#this should find the remaining one utxo and return from it |
||||||
|
assert generate_podle([], tries=tries, allow_external=known_utxos) |
||||||
|
#test commitment removal |
||||||
|
to_remove = ecs[binascii.hexlify(chr(3)*32)] |
||||||
|
update_commitments(external_to_remove={binascii.hexlify(chr(3)*32):to_remove}) |
||||||
|
#test that an incorrectly formatted file raises |
||||||
|
with open(get_commitment_file(), "rb") as f: |
||||||
|
validjson = json.loads(f.read()) |
||||||
|
corruptjson = copy.deepcopy(validjson) |
||||||
|
del corruptjson['used'] |
||||||
|
with open(get_commitment_file(), "wb") as f: |
||||||
|
f.write(json.dumps(corruptjson, indent=4)) |
||||||
|
with pytest.raises(PoDLEError) as e_info: |
||||||
|
get_podle_commitments() |
||||||
|
#clean up |
||||||
|
with open(get_commitment_file(), "wb") as f: |
||||||
|
f.write(json.dumps(validjson, indent=4)) |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def test_podle_constructor(setup_podle): |
||||||
|
"""Tests rules about construction of PoDLE object |
||||||
|
are conformed to. |
||||||
|
""" |
||||||
|
priv = "aa"*32 |
||||||
|
#pub and priv together not allowed |
||||||
|
with pytest.raises(PoDLEError) as e_info: |
||||||
|
p = PoDLE(priv=priv, P="dummypub") |
||||||
|
#no pub or priv is allowed, i forget if this is useful for something |
||||||
|
p = PoDLE() |
||||||
|
#create from priv |
||||||
|
p = PoDLE(priv=priv+"01", u="dummyutxo") |
||||||
|
pdict = p.generate_podle(2) |
||||||
|
assert all([k in pdict for k in ['used', 'utxo', 'P', 'P2', 'commit', 'sig', 'e']]) |
||||||
|
#using the valid data, serialize/deserialize test |
||||||
|
deser = p.deserialize_revelation(p.serialize_revelation()) |
||||||
|
assert all([deser[x] == pdict[x] for x in ['utxo', 'P', 'P2', 'sig', 'e']]) |
||||||
|
#deserialization must fail for wrong number of items |
||||||
|
with pytest.raises(PoDLEError) as e_info: |
||||||
|
p.deserialize_revelation(':'.join([str(x) for x in range(4)]), separator=':') |
||||||
|
#reveal() must work without pre-generated commitment |
||||||
|
p.commitment = None |
||||||
|
pdict2 = p.reveal() |
||||||
|
assert pdict2 == pdict |
||||||
|
#corrupt P2, cannot commit: |
||||||
|
p.P2 = "blah" |
||||||
|
with pytest.raises(PoDLEError) as e_info: |
||||||
|
p.get_commitment() |
||||||
|
#generation fails without a utxo |
||||||
|
p = PoDLE(priv=priv) |
||||||
|
with pytest.raises(PoDLEError) as e_info: |
||||||
|
p.generate_podle(0) |
||||||
|
#Test construction from pubkey |
||||||
|
pub = bitcoin.privkey_to_pubkey(priv+"01") |
||||||
|
p = PoDLE(P=pub) |
||||||
|
with pytest.raises(PoDLEError) as e_info: |
||||||
|
p.get_commitment() |
||||||
|
with pytest.raises(PoDLEError) as e_info: |
||||||
|
p.verify("dummycommitment", range(3)) |
||||||
|
|
||||||
|
def test_podle_error_string(setup_podle): |
||||||
|
priv_utxo_pairs = [('fakepriv1', 'fakeutxo1'), |
||||||
|
('fakepriv2', 'fakeutxo2')] |
||||||
|
to = ['tooold1', 'tooold2'] |
||||||
|
ts = ['toosmall1', 'toosmall2'] |
||||||
|
unspent = "dummyunspent" |
||||||
|
cjamt = 100 |
||||||
|
tua = "3" |
||||||
|
tuamtper = "20" |
||||||
|
errmgsheader, errmsg = generate_podle_error_string(priv_utxo_pairs, |
||||||
|
to, |
||||||
|
ts, |
||||||
|
unspent, |
||||||
|
cjamt, |
||||||
|
tua, |
||||||
|
tuamtper) |
||||||
|
assert errmgsheader == ("Failed to source a commitment; this debugging information" |
||||||
|
" may help:\n\n") |
||||||
|
y = [x[1] for x in priv_utxo_pairs] |
||||||
|
assert all([errmsg.find(x) != -1 for x in to + ts + y]) |
||||||
|
#ensure OK with nothing |
||||||
|
errmgsheader, errmsg = generate_podle_error_string([], [], [], unspent, |
||||||
|
cjamt, tua, tuamtper) |
||||||
|
|
||||||
|
@pytest.fixture(scope="module") |
||||||
|
def setup_podle(request): |
||||||
|
load_program_config() |
||||||
|
if not os.path.exists("cmtdata"): |
||||||
|
os.mkdir("cmtdata") |
||||||
|
prev_commits = False |
||||||
|
#back up any existing commitments |
||||||
|
pcf = get_commitment_file() |
||||||
|
log.debug("Podle file: " + pcf) |
||||||
|
if os.path.exists(pcf): |
||||||
|
os.rename(pcf, pcf + ".bak") |
||||||
|
prev_commits = True |
||||||
|
def teardown(): |
||||||
|
if prev_commits: |
||||||
|
os.rename(pcf + ".bak", pcf) |
||||||
|
else: |
||||||
|
if os.path.exists(pcf): |
||||||
|
os.remove(pcf) |
||||||
|
request.addfinalizer(teardown) |
||||||
@ -0,0 +1,55 @@ |
|||||||
|
#! /usr/bin/env python |
||||||
|
from __future__ import absolute_import |
||||||
|
'''test schedule module.''' |
||||||
|
|
||||||
|
import pytest |
||||||
|
from jmclient import (get_schedule, load_program_config) |
||||||
|
import os |
||||||
|
|
||||||
|
valids = """#sample for testing |
||||||
|
1, 110000000, 3, INTERNAL |
||||||
|
0, 20000000, 2, mnsquzxrHXpFsZeL42qwbKdCP2y1esN3qw |
||||||
|
""" |
||||||
|
|
||||||
|
invalids1 = """#sample for testing |
||||||
|
1, 110000000, 3, 5, INTERNAL |
||||||
|
#pointless comment here; following line has trailing spaces |
||||||
|
0, 20000000, 2, mnsquzxrHXpFsZeL42qwbKdCP2y1esN3qw |
||||||
|
""" |
||||||
|
|
||||||
|
invalids2 = """#sample for testing |
||||||
|
1, 110000000, notinteger, INTERNAL |
||||||
|
0, 20000000, 2, mnsquzxrHXpFsZeL42qwbKdCP2y1esN3qw |
||||||
|
""" |
||||||
|
|
||||||
|
invalids3 = """#sample for testing |
||||||
|
1, 110000000, 3, INTERNAL |
||||||
|
0, notinteger, 2, mnsquzxrHXpFsZeL42qwbKdCP2y1esN3qw |
||||||
|
""" |
||||||
|
|
||||||
|
#invalid address |
||||||
|
invalids4 = """#sample for testing |
||||||
|
1, 110000000, 3, INTERNAL |
||||||
|
0, 20000000, 2, mnsquzxrHXpFsZeL42qwbKdCP2y1esN3qq |
||||||
|
""" |
||||||
|
|
||||||
|
|
||||||
|
def test_get_schedule(): |
||||||
|
load_program_config() |
||||||
|
tsf = "schedulefortesting" |
||||||
|
for s in [valids, invalids1, invalids2, invalids3, invalids4]: |
||||||
|
if os.path.exists(tsf): |
||||||
|
os.remove(tsf) |
||||||
|
with open(tsf, "wb") as f: |
||||||
|
f.write(s) |
||||||
|
result = get_schedule(tsf) |
||||||
|
if s== valids: |
||||||
|
assert result[0] |
||||||
|
assert len(result[1])==2 |
||||||
|
else: |
||||||
|
assert not result[0] |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -0,0 +1,120 @@ |
|||||||
|
#! /usr/bin/env python |
||||||
|
from __future__ import absolute_import |
||||||
|
'''test of the add_tx_notify() timeouts and related callbacks''' |
||||||
|
|
||||||
|
import sys |
||||||
|
|
||||||
|
import time |
||||||
|
from commontest import make_wallets |
||||||
|
import subprocess |
||||||
|
import jmbitcoin as bitcoin |
||||||
|
import pytest |
||||||
|
from jmclient import (load_program_config, jm_single, get_log, Wallet, sync_wallet) |
||||||
|
|
||||||
|
log = get_log() |
||||||
|
|
||||||
|
unconfirm_called = [False] |
||||||
|
confirm_called = [False] |
||||||
|
timeout_unconfirm_called = [False] |
||||||
|
timeout_confirm_called = [False] |
||||||
|
|
||||||
|
def unconfirm_callback(txd, txid): |
||||||
|
unconfirm_called[0] = True |
||||||
|
log.debug('unconfirm callback()') |
||||||
|
|
||||||
|
def confirm_callback(txd, txid, confirmations): |
||||||
|
confirm_called[0] = True |
||||||
|
log.debug('confirm callback()') |
||||||
|
|
||||||
|
def timeout_callback(confirmed): |
||||||
|
if not confirmed: |
||||||
|
timeout_unconfirm_called[0] = True |
||||||
|
log.debug('timeout unconfirm callback()') |
||||||
|
else: |
||||||
|
timeout_confirm_called[0] = True |
||||||
|
log.debug('timeout confirm callback()') |
||||||
|
|
||||||
|
def test_notify_handler_errors(setup_tx_notify): |
||||||
|
#TODO this has hardcoded 62612 which is from regtest_joinmarket.cfg |
||||||
|
#default testing config |
||||||
|
txhex = make_tx_add_notify() |
||||||
|
with pytest.raises(subprocess.CalledProcessError) as e_info: |
||||||
|
res = subprocess.check_output(["curl", "-I", "--connect-timeout", "1", |
||||||
|
"http://localhost:62612/walletnotify?abcd"]) |
||||||
|
with pytest.raises(subprocess.CalledProcessError) as e_info: |
||||||
|
res = subprocess.check_output(["curl", "-I", "--connect-timeout", "1", |
||||||
|
"http://localhost:62612/walletnotify?xxXX"]) |
||||||
|
#unrecognised calls are returned an error message, not a curl failure |
||||||
|
res = subprocess.check_output(["curl", "-I", "--connect-timeout", "1", |
||||||
|
"http://localhost:62612/dummycommand"]) |
||||||
|
#alertnotifys with an alert message should be accepted (todo, deprecate) |
||||||
|
res = subprocess.check_output(["curl", "-I", "--connect-timeout", "1", |
||||||
|
"http://localhost:62612/alertnotify?dummyalertmessage"]) |
||||||
|
|
||||||
|
def test_no_timeout(setup_tx_notify): |
||||||
|
txhex = make_tx_add_notify() |
||||||
|
jm_single().bc_interface.pushtx(txhex) |
||||||
|
time.sleep(6) |
||||||
|
assert unconfirm_called[0] |
||||||
|
assert confirm_called[0] |
||||||
|
assert not timeout_unconfirm_called[0] |
||||||
|
assert not timeout_confirm_called[0] |
||||||
|
return True |
||||||
|
|
||||||
|
def test_unconfirm_timeout(setup_tx_notify): |
||||||
|
txhex = make_tx_add_notify() |
||||||
|
#dont pushtx |
||||||
|
time.sleep(6) |
||||||
|
assert not unconfirm_called[0] |
||||||
|
assert not confirm_called[0] |
||||||
|
assert timeout_unconfirm_called[0] |
||||||
|
assert not timeout_confirm_called[0] |
||||||
|
return True |
||||||
|
|
||||||
|
def test_confirm_timeout(setup_tx_notify): |
||||||
|
txhex = make_tx_add_notify() |
||||||
|
jm_single().bc_interface.tick_forward_chain_interval = -1 |
||||||
|
jm_single().bc_interface.pushtx(txhex) |
||||||
|
time.sleep(10) |
||||||
|
jm_single().bc_interface.tick_forward_chain_interval = 2 |
||||||
|
assert unconfirm_called[0] |
||||||
|
assert not confirm_called[0] |
||||||
|
assert not timeout_unconfirm_called[0] |
||||||
|
assert timeout_confirm_called[0] |
||||||
|
return True |
||||||
|
|
||||||
|
def make_tx_add_notify(): |
||||||
|
wallet_dict = make_wallets(1, [[1, 0, 0, 0, 0]], mean_amt=4, sdev_amt=0)[0] |
||||||
|
amount = 250000000 |
||||||
|
txfee = 10000 |
||||||
|
wallet = wallet_dict['wallet'] |
||||||
|
sync_wallet(wallet) |
||||||
|
inputs = wallet.select_utxos(0, amount) |
||||||
|
ins = inputs.keys() |
||||||
|
input_value = sum([i['value'] for i in inputs.values()]) |
||||||
|
output_addr = wallet.get_new_addr(1, 0) |
||||||
|
change_addr = wallet.get_new_addr(0, 1) |
||||||
|
outs = [{'value': amount, 'address': output_addr}, |
||||||
|
{'value': input_value - amount - txfee, 'address': change_addr}] |
||||||
|
tx = bitcoin.mktx(ins, outs) |
||||||
|
de_tx = bitcoin.deserialize(tx) |
||||||
|
for index, ins in enumerate(de_tx['ins']): |
||||||
|
utxo = ins['outpoint']['hash'] + ':' + str(ins['outpoint']['index']) |
||||||
|
addr = inputs[utxo]['address'] |
||||||
|
priv = wallet.get_key_from_addr(addr) |
||||||
|
tx = bitcoin.sign(tx, index, priv) |
||||||
|
|
||||||
|
unconfirm_called[0] = confirm_called[0] = False |
||||||
|
timeout_unconfirm_called[0] = timeout_confirm_called[0] = False |
||||||
|
jm_single().bc_interface.add_tx_notify( |
||||||
|
bitcoin.deserialize(tx), unconfirm_callback, |
||||||
|
confirm_callback, output_addr, timeout_callback) |
||||||
|
return tx |
||||||
|
|
||||||
|
@pytest.fixture(scope="module") |
||||||
|
def setup_tx_notify(): |
||||||
|
load_program_config() |
||||||
|
jm_single().config.set('TIMEOUT', 'unconfirm_timeout_sec', '3') |
||||||
|
jm_single().config.set('TIMEOUT', 'confirm_timeout_hours', str(6.0 / 60 / 60)) |
||||||
|
jm_single().bc_interface.tick_forward_chain_interval = 2 |
||||||
|
|
||||||
Loading…
Reference in new issue