2018-01-15 22:23:44 +01:00
#!/usr/bin/env python3
# Copyright (c) 2018 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
""" Test the scantxoutset rpc call. """
from test_framework . test_framework import BitcoinTestFramework
2019-05-10 14:09:34 +02:00
from test_framework . util import assert_equal , assert_raises_rpc_error , Decimal
2018-01-15 22:23:44 +01:00
import shutil
import os
2018-10-13 03:22:22 +02:00
def descriptors ( out ) :
return sorted ( u [ ' desc ' ] for u in out [ ' unspents ' ] )
2018-01-15 22:23:44 +01:00
class ScantxoutsetTest ( BitcoinTestFramework ) :
def set_test_params ( self ) :
self . num_nodes = 1
self . setup_clean_chain = True
2018-09-13 12:33:15 +02:00
def skip_test_if_missing_module ( self ) :
self . skip_if_no_wallet ( )
2018-01-15 22:23:44 +01:00
def run_test ( self ) :
self . log . info ( " Mining blocks... " )
self . nodes [ 0 ] . generate ( 110 )
2021-07-20 17:52:47 +02:00
addr1 = self . nodes [ 0 ] . getnewaddress ( " " )
pubk1 = self . nodes [ 0 ] . getaddressinfo ( addr1 ) [ ' pubkey ' ]
addr2 = self . nodes [ 0 ] . getnewaddress ( " " )
pubk2 = self . nodes [ 0 ] . getaddressinfo ( addr2 ) [ ' pubkey ' ]
addr3 = self . nodes [ 0 ] . getnewaddress ( " " )
pubk3 = self . nodes [ 0 ] . getaddressinfo ( addr3 ) [ ' pubkey ' ]
self . nodes [ 0 ] . sendtoaddress ( addr1 , 0.001 )
self . nodes [ 0 ] . sendtoaddress ( addr2 , 0.002 )
self . nodes [ 0 ] . sendtoaddress ( addr3 , 0.004 )
2021-07-20 17:59:35 +02:00
#send to child keys of tprv8ZgxMBicQKsPd7Uf69XL1XwhmjHopUGep8GuEiJDZmbQz6o58LninorQAfcKZWARbtRtfnLcJ5MQ2AtHcQJCCRUcMRvmDUjyEmNUWwx8UbK
2021-07-20 17:52:47 +02:00
self . nodes [ 0 ] . sendtoaddress ( " yR5yZLjevw5kX3UxGiQN1g96LXGJni2wSS " , 0.008 ) # (m/0'/0'/0')
self . nodes [ 0 ] . sendtoaddress ( " yPcxzaQekxTjaJVSaZ58r22o37H8moWPK2 " , 0.016 ) # (m/0'/0'/1')
self . nodes [ 0 ] . sendtoaddress ( " yhv7iRHSx4SgyvCPmkm6Js8gTuJTtJH9ec " , 0.032 ) # (m/0'/0'/1500')
self . nodes [ 0 ] . sendtoaddress ( " yWEdyyKVNbmaiXHkg3LVPqgoXpMA3S6Xt7 " , 0.064 ) # (m/0'/0'/0)
self . nodes [ 0 ] . sendtoaddress ( " yTGAdq8sSHJ1QrcqSUaMHs8RMj3Bqz3bkb " , 0.128 ) # (m/0'/0'/1)
self . nodes [ 0 ] . sendtoaddress ( " yRTNkmjXjhatND4Dv3V4GwBzYJQ4o9ukQr " , 0.256 ) # (m/0'/0'/1500)
self . nodes [ 0 ] . sendtoaddress ( " yPwUp9Vwmr4zE6rSuZg3TBxeyRerdRAbNd " , 0.512 ) # (m/1/1/0')
self . nodes [ 0 ] . sendtoaddress ( " yLapNU3bG8E8JNGXRhZbRHHDifrqTucGcg " , 1.024 ) # (m/1/1/1')
self . nodes [ 0 ] . sendtoaddress ( " yUhbAKf7AcTC5sPXb2dkABKm3FYENqdzv2 " , 2.048 ) # (m/1/1/1500')
self . nodes [ 0 ] . sendtoaddress ( " yZTyMdEJjZWJi6CwY6g3WurLESH3UsWrrM " , 4.096 ) # (m/1/1/0)
self . nodes [ 0 ] . sendtoaddress ( " ydccVGNV2EcEouAxbbgdu8pi8gkdaqkiav " , 8.192 ) # (m/1/1/1)
self . nodes [ 0 ] . sendtoaddress ( " yVCdQxPXJ3SrtTLv8FuLXDNaynz6kmjPNq " , 16.384 ) # (m/1/1/1500)
2021-07-20 17:59:35 +02:00
2018-01-15 22:23:44 +01:00
self . nodes [ 0 ] . generate ( 1 )
self . log . info ( " Stop node, remove wallet, mine again some blocks... " )
self . stop_node ( 0 )
shutil . rmtree ( os . path . join ( self . nodes [ 0 ] . datadir , " regtest " , ' wallets ' ) )
self . start_node ( 0 )
self . nodes [ 0 ] . generate ( 110 )
self . restart_node ( 0 , [ ' -nowallet ' ] )
self . log . info ( " Test if we have found the non HD unspent outputs. " )
2021-07-20 17:52:47 +02:00
assert_equal ( self . nodes [ 0 ] . scantxoutset ( " start " , [ " pkh( " + pubk1 + " ) " , " pkh( " + pubk2 + " ) " , " pkh( " + pubk3 + " ) " ] ) [ ' total_amount ' ] , Decimal ( " 0.007 " ) )
2021-07-20 17:59:35 +02:00
assert_equal ( self . nodes [ 0 ] . scantxoutset ( " start " , [ " combo( " + pubk1 + " ) " , " combo( " + pubk2 + " ) " , " combo( " + pubk3 + " ) " ] ) [ ' total_amount ' ] , Decimal ( " 0.007 " ) )
2021-07-20 17:52:47 +02:00
assert_equal ( self . nodes [ 0 ] . scantxoutset ( " start " , [ " addr( " + addr1 + " ) " , " addr( " + addr2 + " ) " , " combo( " + pubk3 + " ) " ] ) [ ' total_amount ' ] , Decimal ( " 0.007 " ) )
assert_equal ( self . nodes [ 0 ] . scantxoutset ( " start " , [ " addr( " + addr1 + " ) " , " addr( " + addr2 + " ) " , " addr( " + addr3 + " ) " ] ) [ ' total_amount ' ] , Decimal ( " 0.007 " ) )
assert_equal ( self . nodes [ 0 ] . scantxoutset ( " start " , [ " addr( " + addr1 + " ) " , " addr( " + addr2 + " ) " , " pkh( " + pubk3 + " ) " ] ) [ ' total_amount ' ] , Decimal ( " 0.007 " ) )
2018-01-15 22:23:44 +01:00
2019-05-10 14:09:34 +02:00
self . log . info ( " Test range validation. " )
assert_raises_rpc_error ( - 8 , " End of range is too high " , self . nodes [ 0 ] . scantxoutset , " start " , [ { " desc " : " desc " , " range " : - 1 } ] )
assert_raises_rpc_error ( - 8 , " Range should be greater or equal than 0 " , self . nodes [ 0 ] . scantxoutset , " start " , [ { " desc " : " desc " , " range " : [ - 1 , 10 ] } ] )
assert_raises_rpc_error ( - 8 , " End of range is too high " , self . nodes [ 0 ] . scantxoutset , " start " , [ { " desc " : " desc " , " range " : [ ( 2 << 31 + 1 ) - 1000000 , ( 2 << 31 + 1 ) ] } ] )
assert_raises_rpc_error ( - 8 , " Range specified as [begin,end] must not have begin after end " , self . nodes [ 0 ] . scantxoutset , " start " , [ { " desc " : " desc " , " range " : [ 2 , 1 ] } ] )
assert_raises_rpc_error ( - 8 , " Range is too large " , self . nodes [ 0 ] . scantxoutset , " start " , [ { " desc " : " desc " , " range " : [ 0 , 1000001 ] } ] )
2021-07-20 17:59:35 +02:00
self . log . info ( " Test extended key derivation. " )
2021-10-28 07:26:04 +02:00
# Run various scans, and verify that the sum of the amounts of the matches corresponds to the expected subset.
# Note that all amounts in the UTXO set are powers of 2 multiplied by 0.001 BTC, so each amounts uniquely identifies a subset.
2021-07-20 17:59:35 +02:00
assert_equal ( self . nodes [ 0 ] . scantxoutset ( " start " , [ " combo(tprv8ZgxMBicQKsPd7Uf69XL1XwhmjHopUGep8GuEiJDZmbQz6o58LninorQAfcKZWARbtRtfnLcJ5MQ2AtHcQJCCRUcMRvmDUjyEmNUWwx8UbK/0 ' /0h/0h) " ] ) [ ' total_amount ' ] , Decimal ( " 0.008 " ) )
assert_equal ( self . nodes [ 0 ] . scantxoutset ( " start " , [ " combo(tprv8ZgxMBicQKsPd7Uf69XL1XwhmjHopUGep8GuEiJDZmbQz6o58LninorQAfcKZWARbtRtfnLcJ5MQ2AtHcQJCCRUcMRvmDUjyEmNUWwx8UbK/0 ' /0 ' /1h) " ] ) [ ' total_amount ' ] , Decimal ( " 0.016 " ) )
assert_equal ( self . nodes [ 0 ] . scantxoutset ( " start " , [ " combo(tprv8ZgxMBicQKsPd7Uf69XL1XwhmjHopUGep8GuEiJDZmbQz6o58LninorQAfcKZWARbtRtfnLcJ5MQ2AtHcQJCCRUcMRvmDUjyEmNUWwx8UbK/0h/0 ' /1500 ' ) " ] ) [ ' total_amount ' ] , Decimal ( " 0.032 " ) )
assert_equal ( self . nodes [ 0 ] . scantxoutset ( " start " , [ " combo(tprv8ZgxMBicQKsPd7Uf69XL1XwhmjHopUGep8GuEiJDZmbQz6o58LninorQAfcKZWARbtRtfnLcJ5MQ2AtHcQJCCRUcMRvmDUjyEmNUWwx8UbK/0h/0h/0) " ] ) [ ' total_amount ' ] , Decimal ( " 0.064 " ) )
assert_equal ( self . nodes [ 0 ] . scantxoutset ( " start " , [ " combo(tprv8ZgxMBicQKsPd7Uf69XL1XwhmjHopUGep8GuEiJDZmbQz6o58LninorQAfcKZWARbtRtfnLcJ5MQ2AtHcQJCCRUcMRvmDUjyEmNUWwx8UbK/0 ' /0h/1) " ] ) [ ' total_amount ' ] , Decimal ( " 0.128 " ) )
assert_equal ( self . nodes [ 0 ] . scantxoutset ( " start " , [ " combo(tprv8ZgxMBicQKsPd7Uf69XL1XwhmjHopUGep8GuEiJDZmbQz6o58LninorQAfcKZWARbtRtfnLcJ5MQ2AtHcQJCCRUcMRvmDUjyEmNUWwx8UbK/0h/0 ' /1500) " ] ) [ ' total_amount ' ] , Decimal ( " 0.256 " ) )
assert_equal ( self . nodes [ 0 ] . scantxoutset ( " start " , [ { " desc " : " combo(tprv8ZgxMBicQKsPd7Uf69XL1XwhmjHopUGep8GuEiJDZmbQz6o58LninorQAfcKZWARbtRtfnLcJ5MQ2AtHcQJCCRUcMRvmDUjyEmNUWwx8UbK/0 ' /0h/*h) " , " range " : 1499 } ] ) [ ' total_amount ' ] , Decimal ( " 0.024 " ) )
assert_equal ( self . nodes [ 0 ] . scantxoutset ( " start " , [ { " desc " : " combo(tprv8ZgxMBicQKsPd7Uf69XL1XwhmjHopUGep8GuEiJDZmbQz6o58LninorQAfcKZWARbtRtfnLcJ5MQ2AtHcQJCCRUcMRvmDUjyEmNUWwx8UbK/0 ' /0 ' /*h) " , " range " : 1500 } ] ) [ ' total_amount ' ] , Decimal ( " 0.056 " ) )
assert_equal ( self . nodes [ 0 ] . scantxoutset ( " start " , [ { " desc " : " combo(tprv8ZgxMBicQKsPd7Uf69XL1XwhmjHopUGep8GuEiJDZmbQz6o58LninorQAfcKZWARbtRtfnLcJ5MQ2AtHcQJCCRUcMRvmDUjyEmNUWwx8UbK/0h/0 ' /*) " , " range " : 1499 } ] ) [ ' total_amount ' ] , Decimal ( " 0.192 " ) )
assert_equal ( self . nodes [ 0 ] . scantxoutset ( " start " , [ { " desc " : " combo(tprv8ZgxMBicQKsPd7Uf69XL1XwhmjHopUGep8GuEiJDZmbQz6o58LninorQAfcKZWARbtRtfnLcJ5MQ2AtHcQJCCRUcMRvmDUjyEmNUWwx8UbK/0 ' /0h/*) " , " range " : 1500 } ] ) [ ' total_amount ' ] , Decimal ( " 0.448 " ) )
assert_equal ( self . nodes [ 0 ] . scantxoutset ( " start " , [ " combo(tprv8ZgxMBicQKsPd7Uf69XL1XwhmjHopUGep8GuEiJDZmbQz6o58LninorQAfcKZWARbtRtfnLcJ5MQ2AtHcQJCCRUcMRvmDUjyEmNUWwx8UbK/1/1/0 ' ) " ] ) [ ' total_amount ' ] , Decimal ( " 0.512 " ) )
assert_equal ( self . nodes [ 0 ] . scantxoutset ( " start " , [ " combo(tprv8ZgxMBicQKsPd7Uf69XL1XwhmjHopUGep8GuEiJDZmbQz6o58LninorQAfcKZWARbtRtfnLcJ5MQ2AtHcQJCCRUcMRvmDUjyEmNUWwx8UbK/1/1/1 ' ) " ] ) [ ' total_amount ' ] , Decimal ( " 1.024 " ) )
assert_equal ( self . nodes [ 0 ] . scantxoutset ( " start " , [ " combo(tprv8ZgxMBicQKsPd7Uf69XL1XwhmjHopUGep8GuEiJDZmbQz6o58LninorQAfcKZWARbtRtfnLcJ5MQ2AtHcQJCCRUcMRvmDUjyEmNUWwx8UbK/1/1/1500h) " ] ) [ ' total_amount ' ] , Decimal ( " 2.048 " ) )
assert_equal ( self . nodes [ 0 ] . scantxoutset ( " start " , [ " combo(tprv8ZgxMBicQKsPd7Uf69XL1XwhmjHopUGep8GuEiJDZmbQz6o58LninorQAfcKZWARbtRtfnLcJ5MQ2AtHcQJCCRUcMRvmDUjyEmNUWwx8UbK/1/1/0) " ] ) [ ' total_amount ' ] , Decimal ( " 4.096 " ) )
assert_equal ( self . nodes [ 0 ] . scantxoutset ( " start " , [ " combo(tprv8ZgxMBicQKsPd7Uf69XL1XwhmjHopUGep8GuEiJDZmbQz6o58LninorQAfcKZWARbtRtfnLcJ5MQ2AtHcQJCCRUcMRvmDUjyEmNUWwx8UbK/1/1/1) " ] ) [ ' total_amount ' ] , Decimal ( " 8.192 " ) )
assert_equal ( self . nodes [ 0 ] . scantxoutset ( " start " , [ " combo(tprv8ZgxMBicQKsPd7Uf69XL1XwhmjHopUGep8GuEiJDZmbQz6o58LninorQAfcKZWARbtRtfnLcJ5MQ2AtHcQJCCRUcMRvmDUjyEmNUWwx8UbK/1/1/1500) " ] ) [ ' total_amount ' ] , Decimal ( " 16.384 " ) )
assert_equal ( self . nodes [ 0 ] . scantxoutset ( " start " , [ " combo(tpubD6NzVbkrYhZ4WaWSyoBvQwbpLkojyoTZPRsgXELWz3Popb3qkjcJyJUGLnL4qHHoQvao8ESaAstxYSnhyswJ76uZPStJRJCTKvosUCJZL5B/1/1/0) " ] ) [ ' total_amount ' ] , Decimal ( " 4.096 " ) )
2021-10-28 07:26:04 +02:00
assert_equal ( self . nodes [ 0 ] . scantxoutset ( " start " , [ " combo([abcdef88/1/2 ' /3/4h]tpubD6NzVbkrYhZ4WaWSyoBvQwbpLkojyoTZPRsgXELWz3Popb3qkjcJyJUGLnL4qHHoQvao8ESaAstxYSnhyswJ76uZPStJRJCTKvosUCJZL5B/1/1/1) " ] ) [ ' total_amount ' ] , Decimal ( " 8.192 " ) )
2021-07-20 17:59:35 +02:00
assert_equal ( self . nodes [ 0 ] . scantxoutset ( " start " , [ " combo(tpubD6NzVbkrYhZ4WaWSyoBvQwbpLkojyoTZPRsgXELWz3Popb3qkjcJyJUGLnL4qHHoQvao8ESaAstxYSnhyswJ76uZPStJRJCTKvosUCJZL5B/1/1/1500) " ] ) [ ' total_amount ' ] , Decimal ( " 16.384 " ) )
assert_equal ( self . nodes [ 0 ] . scantxoutset ( " start " , [ { " desc " : " combo(tprv8ZgxMBicQKsPd7Uf69XL1XwhmjHopUGep8GuEiJDZmbQz6o58LninorQAfcKZWARbtRtfnLcJ5MQ2AtHcQJCCRUcMRvmDUjyEmNUWwx8UbK/1/1/* ' ) " , " range " : 1499 } ] ) [ ' total_amount ' ] , Decimal ( " 1.536 " ) )
assert_equal ( self . nodes [ 0 ] . scantxoutset ( " start " , [ { " desc " : " combo(tprv8ZgxMBicQKsPd7Uf69XL1XwhmjHopUGep8GuEiJDZmbQz6o58LninorQAfcKZWARbtRtfnLcJ5MQ2AtHcQJCCRUcMRvmDUjyEmNUWwx8UbK/1/1/* ' ) " , " range " : 1500 } ] ) [ ' total_amount ' ] , Decimal ( " 3.584 " ) )
assert_equal ( self . nodes [ 0 ] . scantxoutset ( " start " , [ { " desc " : " combo(tprv8ZgxMBicQKsPd7Uf69XL1XwhmjHopUGep8GuEiJDZmbQz6o58LninorQAfcKZWARbtRtfnLcJ5MQ2AtHcQJCCRUcMRvmDUjyEmNUWwx8UbK/1/1/*) " , " range " : 1499 } ] ) [ ' total_amount ' ] , Decimal ( " 12.288 " ) )
assert_equal ( self . nodes [ 0 ] . scantxoutset ( " start " , [ { " desc " : " combo(tprv8ZgxMBicQKsPd7Uf69XL1XwhmjHopUGep8GuEiJDZmbQz6o58LninorQAfcKZWARbtRtfnLcJ5MQ2AtHcQJCCRUcMRvmDUjyEmNUWwx8UbK/1/1/*) " , " range " : 1500 } ] ) [ ' total_amount ' ] , Decimal ( " 28.672 " ) )
assert_equal ( self . nodes [ 0 ] . scantxoutset ( " start " , [ { " desc " : " combo(tpubD6NzVbkrYhZ4WaWSyoBvQwbpLkojyoTZPRsgXELWz3Popb3qkjcJyJUGLnL4qHHoQvao8ESaAstxYSnhyswJ76uZPStJRJCTKvosUCJZL5B/1/1/*) " , " range " : 1499 } ] ) [ ' total_amount ' ] , Decimal ( " 12.288 " ) )
assert_equal ( self . nodes [ 0 ] . scantxoutset ( " start " , [ { " desc " : " combo(tpubD6NzVbkrYhZ4WaWSyoBvQwbpLkojyoTZPRsgXELWz3Popb3qkjcJyJUGLnL4qHHoQvao8ESaAstxYSnhyswJ76uZPStJRJCTKvosUCJZL5B/1/1/*) " , " range " : 1500 } ] ) [ ' total_amount ' ] , Decimal ( " 28.672 " ) )
Merge #15497: rpc: Consistent range arguments in scantxoutset/importmulti/deriveaddresses
ca253f6ebf Make deriveaddresses use stop/[start,stop] notation for ranges (Pieter Wuille)
1675b7ce55 Use stop/[start,stop] notation in importmulti desc range (Pieter Wuille)
4566011631 Add support for stop/[start,stop] ranges to scantxoutset (Pieter Wuille)
6b9f45e81b Support ranges arguments in RPC help (Pieter Wuille)
7aa6a8aefb Add ParseRange function to parse args of the form int/[int,int] (Pieter Wuille)
Pull request description:
This introduces a consistent notation for RPC arguments in `scantxoutset`, `importmulti`, and `deriveaddresses`, either:
* `"range" : int` to just specify the end of the range
* `"range" : [int,int]` to specify both the begin and the end of the range.
For `scantxoutset`, this is a backward compatible new feature. For the two other RPCs, it's an incompatible change, but neither of them has been in a release so far. Because of that non-released reason, this only makes sense in 0.18, in my opinion.
I suggest this as an alternative to #15496, which only makes `deriveaddresses` compatible with `importmulti`, but not with the existing `scantxoutset` RPC. I also think `[int,int]` is more convenient than `{"start":int,"stop":int}`.
I realize this is technically a feature added to `scantxoutset` after the feature freeze. If desired, I'll drop the `scantxoutset` changes.
Tree-SHA512: 1cbebb90cf34f106786dbcec7afbf3f43fb8b7e46cc7e6763faf1bc1babf12375a1b3c3cf86ee83c21ed2171d99b5a2f60331850bc613db25538c38b6a056676
2019-03-01 15:13:05 +01:00
assert_equal ( self . nodes [ 0 ] . scantxoutset ( " start " , [ { " desc " : " combo(tpubD6NzVbkrYhZ4WaWSyoBvQwbpLkojyoTZPRsgXELWz3Popb3qkjcJyJUGLnL4qHHoQvao8ESaAstxYSnhyswJ76uZPStJRJCTKvosUCJZL5B/1/1/*) " , " range " : [ 1500 , 1500 ] } ] ) [ ' total_amount ' ] , Decimal ( " 16.384 " ) )
2018-01-15 22:23:44 +01:00
2018-10-13 03:22:22 +02:00
# Test the reported descriptors for a few matches
2021-10-28 09:57:55 +02:00
assert_equal ( descriptors ( self . nodes [ 0 ] . scantxoutset ( " start " , [ { " desc " : " combo(tprv8ZgxMBicQKsPd7Uf69XL1XwhmjHopUGep8GuEiJDZmbQz6o58LninorQAfcKZWARbtRtfnLcJ5MQ2AtHcQJCCRUcMRvmDUjyEmNUWwx8UbK/0h/0 ' /*) " , " range " : 1499 } ] ) ) , [ " pkh([0c5f9a1e/0 ' /0 ' /0]026dbd8b2315f296d36e6b6920b1579ca75569464875c7ebe869b536a7d9503c8c)#dzxw429x " , " pkh([0c5f9a1e/0 ' /0 ' /1]033e6f25d76c00bedb3a8993c7d5739ee806397f0529b1b31dda31ef890f19a60c)#43rvceed " ] )
assert_equal ( descriptors ( self . nodes [ 0 ] . scantxoutset ( " start " , [ " combo(tprv8ZgxMBicQKsPd7Uf69XL1XwhmjHopUGep8GuEiJDZmbQz6o58LninorQAfcKZWARbtRtfnLcJ5MQ2AtHcQJCCRUcMRvmDUjyEmNUWwx8UbK/1/1/0) " ] ) ) , [ " pkh([0c5f9a1e/1/1/0]03e1c5b6e650966971d7e71ef2674f80222752740fc1dfd63bbbd220d2da9bd0fb)#cxmct4w8 " ] )
assert_equal ( descriptors ( self . nodes [ 0 ] . scantxoutset ( " start " , [ { " desc " : " combo(tpubD6NzVbkrYhZ4WaWSyoBvQwbpLkojyoTZPRsgXELWz3Popb3qkjcJyJUGLnL4qHHoQvao8ESaAstxYSnhyswJ76uZPStJRJCTKvosUCJZL5B/1/1/*) " , " range " : 1500 } ] ) ) , [ ' pkh([0c5f9a1e/1/1/0]03e1c5b6e650966971d7e71ef2674f80222752740fc1dfd63bbbd220d2da9bd0fb)#cxmct4w8 ' , ' pkh([0c5f9a1e/1/1/1500]03832901c250025da2aebae2bfb38d5c703a57ab66ad477f9c578bfbcd78abca6f)#vchwd07g ' , ' pkh([0c5f9a1e/1/1/1]030d820fc9e8211c4169be8530efbc632775d8286167afd178caaf1089b77daba7)#z2t3ypsa ' ] )
2018-10-13 03:22:22 +02:00
2018-01-15 22:23:44 +01:00
if __name__ == ' __main__ ' :
ScantxoutsetTest ( ) . main ( )