Initial commit: snapshot of spesmilo/electrumx 2.0.0
Unmodified source tree of upstream commit 280cb339aa158e099eb936033eecd15719770651
("Merge pull request #389 from SomberNight/202607_release_2_0",
https://github.com/spesmilo/electrumx, release 2.0.0, 3 July 2026).
All Palladium-specific changes are in the commits that follow.
This commit is contained in:
commit
384d907c65
271 files changed
+27905
No files matched your search
Whitespace-only changes.
@@ -0,0 +1,88 @@
|
||||
# Copyright (c) 2017, the ElectrumX authors
|
||||
#
|
||||
# All rights reserved.
|
||||
#
|
||||
# The MIT License (MIT)
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
# "Software"), to deal in the Software without restriction, including
|
||||
# without limitation the rights to use, copy, modify, merge, publish,
|
||||
# distribute, sublicense, and/or sell copies of the Software, and to
|
||||
# permit persons to whom the Software is furnished to do so, subject to
|
||||
# the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be
|
||||
# included in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
# and warranty status of this software.
|
||||
|
||||
import pytest
|
||||
|
||||
import electrumx.lib.coins as coins
|
||||
|
||||
addresses = [
|
||||
(coins.BitcoinCash, "13xDKJbjh4acmLpNVr6Lc9hFcXRr9fyt4x",
|
||||
"206168f5322583ff37f8e55665a4789ae8963532", "b8cb80b26e8932f5b12a7e"),
|
||||
(coins.BitcoinCash, "3GxRZWkJufR5XA8hnNJgQ2gkASSheoBcmW",
|
||||
"a773db925b09add367dcc253c1f9bbc1d11ec6fd", "062d8515e50cb92b8a3a73"),
|
||||
(coins.BitcoinGold, "GZjH8pETu5xXd5DTt5VAqS9giooLNoHjnJ",
|
||||
"ae40655d7006806fd668248d10e7822c0b774dab", "3a1af301b378ad92493b17"),
|
||||
(coins.BitcoinGold, "AXfENBm9FP1PMa8AWnVPZZ4tHEwBiqNZav",
|
||||
"ae40655d7006806fd668248d10e7822c0b774dab", "cb3db4271432c0ac9f88d5"),
|
||||
(coins.Emercoin, "ELAeVHQg2mmdTTrTrZSzMgAQyXfC9TSRys",
|
||||
"210c4482ad8eacb0d349992973608300677adb15", "d71f2df4ef1b397088d731"),
|
||||
(coins.Litecoin, "LNBAaWuZmipg29WXfz5dtAm1pjo8FEH8yg",
|
||||
"206168f5322583ff37f8e55665a4789ae8963532", "b8cb80b26e8932f5b12a7e"),
|
||||
(coins.Litecoin, "MPAZsQAGrnGWKfQbtFJ2Dfw9V939e7D3E2",
|
||||
"a773db925b09add367dcc253c1f9bbc1d11ec6fd", "062d8515e50cb92b8a3a73"),
|
||||
(coins.Zcash, "t1LppKe1sfPNDMysGSGuTjxoAsBcvvSYv5j",
|
||||
"206168f5322583ff37f8e55665a4789ae8963532", "b8cb80b26e8932f5b12a7e"),
|
||||
(coins.Zcash, "t3Zq2ZrASszCg7oBbio7oXqnfR6dnSWqo76",
|
||||
"a773db925b09add367dcc253c1f9bbc1d11ec6fd", "062d8515e50cb92b8a3a73"),
|
||||
(coins.Decred, "DsUZxxoHJSty8DCfwfartwTYbuhmVct7tJu",
|
||||
"2789d58cfa0957d206f025c2af056fc8a77cebb0", "8cc9b11122272bd7b79a50"),
|
||||
(coins.Decred, "DcuQKx8BES9wU7C6Q5VmLBjw436r27hayjS",
|
||||
"f0b4e85100aee1a996f22915eb3c3f764d53779a", "a03c1a27de9ac3b3122e8d"),
|
||||
(coins.Groestlcoin, "FY7vmDL7FZGACwqVNx5p4fVaGghojWM5AF",
|
||||
"206168f5322583ff37f8e55665a4789ae8963532", "b8cb80b26e8932f5b12a7e"),
|
||||
(coins.Bitg, "GP1vBChXjjbaKwMcoPGB4T8cZLXWCe2wLV",
|
||||
"38bc968f95157bb7446feb1a7d75f2791fc8cf91", "4c7332cd142b788dd89241"),
|
||||
(coins.Bitg, "GaXGkXrm4dK1CYfSWvKubKgMcrYN59BZGF",
|
||||
"b6f335a20a887f03a1d8a5c701f967c35d9b45c4", "383b20a90a9109531ccd7e"),
|
||||
(coins.Pivx, "DGSHy3fsygJTZtvnkpT1qG8QvNim5kwyqp",
|
||||
"7be9fe7b9f894ba8481814c5eb085b788597059a", "9f1c9c70216bdc67a897fc"),
|
||||
(coins.Pivx, "DSHxy3zZLUxZndKtXq9rXhwAMH1Ypt8qEW",
|
||||
"e808105b7bfcc8b102cafa7242089b22c77a3b94", "31d61c3076fa0b2b7c74ef"),
|
||||
(coins.PivxTestnet, "yJ8iHtUxj9U4vsXLCZTbPNbuxG6NJNCvb8",
|
||||
"e808105b7bfcc8b102cafa7242089b22c77a3b94", "31d61c3076fa0b2b7c74ef"),
|
||||
(coins.PivxTestnet, "yCcNWqqMhDmsPzKchCPK1ux4HpxK7j3xpB",
|
||||
"ab72728952c06dfc0f6cf21449dd645422731ec4", "eb3a3155215538d51de7cc"),
|
||||
(coins.TokenPay, "TDE2X28FGtckatxuP3d8s3V726G4TLNHpT",
|
||||
"23b5dd9b7b402388c7a40bc88c261f3178acf30d", "7c7bdf0e0713f3752f4b88"),
|
||||
(coins.SmartCash, "SQFDM9NtRRmpHebq3H5RA3qpGJfGqp8Xgw",
|
||||
"206168f5322583ff37f8e55665a4789ae8963532", "b8cb80b26e8932f5b12a7e"),
|
||||
(coins.Peercoin, "PAprodbYvZqf4vjhef49aThB9rSZRxXsM6",
|
||||
"1886c1b26e9546e8d424eb79631ee68de134466b", "2a9d25cb0c9f05690bff89"),
|
||||
(coins.PeercoinTestnet, "msnHPXDWuJhRBPVNQnwXdKvEMQHLr9z1P5",
|
||||
"8687b01c03f47615226bdf54443f172d8eb523c6", "318a000ccf626685c8c213"),
|
||||
(coins.GravityZeroCoin, "GJPaFtL7ffbFPQKbPoLn2PvgajQ48QGo67",
|
||||
"05fc7b8c8ba198dedb4d14223aeb709436373d6b", "bd8fa7f0c7b50b023ac0c6"),
|
||||
]
|
||||
|
||||
|
||||
@pytest.fixture(params=addresses)
|
||||
def address(request):
|
||||
return request.param
|
||||
|
||||
|
||||
def test_address_to_hashX(address):
|
||||
coin, addr, _, hashX = address
|
||||
assert coin.address_to_hashX(addr).hex() == hashX
|
||||
@@ -0,0 +1,98 @@
|
||||
# Tests of lib/coins.py
|
||||
|
||||
import pytest
|
||||
|
||||
from electrumx.lib.coins import NameMixin
|
||||
from electrumx.lib.script import OpCodes, Script
|
||||
|
||||
|
||||
NAME = "name".encode("ascii")
|
||||
DAYS = hex(6).encode("ascii")
|
||||
VALUE = "value".encode("ascii")
|
||||
ADDRESS_SCRIPT = "address_script".encode("ascii")
|
||||
|
||||
OP_NAME_NEW = OpCodes.OP_1
|
||||
OP_NAME_UPDATE = OpCodes.OP_2
|
||||
OP_DROP = OpCodes.OP_DROP
|
||||
OP_2DROP = OpCodes.OP_2DROP
|
||||
DP_MULT = NameMixin.DATA_PUSH_MULTIPLE
|
||||
|
||||
|
||||
def create_script(pattern, address_script):
|
||||
script = bytearray()
|
||||
for item in pattern:
|
||||
if type(item) == int:
|
||||
script.append(item)
|
||||
else:
|
||||
script.extend(Script.push_data(item))
|
||||
script.extend(address_script)
|
||||
|
||||
return bytes(script)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("opcode,pattern", (
|
||||
([OP_NAME_NEW, OP_DROP, -1, -1, OP_2DROP, -1, OP_DROP],
|
||||
[OP_NAME_NEW, OP_DROP, NAME, DAYS, OP_2DROP, VALUE, OP_DROP]),
|
||||
|
||||
([OP_NAME_NEW, OP_DROP, -1, -1, OP_2DROP, DP_MULT],
|
||||
[OP_NAME_NEW, OP_DROP, NAME, DAYS, OP_2DROP, VALUE, OP_DROP]),
|
||||
([OP_NAME_NEW, OP_DROP, -1, -1, OP_2DROP, DP_MULT],
|
||||
[OP_NAME_NEW, OP_DROP, NAME, DAYS, OP_2DROP, VALUE, VALUE, OP_2DROP]),
|
||||
|
||||
([OP_NAME_NEW, OP_DROP, -1, OP_2DROP, DP_MULT, -1, OP_DROP],
|
||||
[OP_NAME_NEW, OP_DROP, NAME, OP_2DROP, VALUE, OP_DROP, DAYS, OP_DROP]),
|
||||
([OP_NAME_NEW, OP_DROP, -1, OP_2DROP, DP_MULT, -1, OP_DROP],
|
||||
[OP_NAME_NEW, OP_DROP, NAME, OP_2DROP, VALUE, VALUE, OP_2DROP, DAYS, OP_DROP]),
|
||||
))
|
||||
def test_name_mixin_interpret_name_prefix(opcode, pattern):
|
||||
ops = [opcode]
|
||||
script = create_script(pattern, ADDRESS_SCRIPT)
|
||||
parsed_names, parsed_address_script = NameMixin.interpret_name_prefix(script, ops)
|
||||
|
||||
assert len(parsed_names) == 0
|
||||
assert parsed_address_script == ADDRESS_SCRIPT
|
||||
|
||||
|
||||
@pytest.mark.parametrize("opcode,pattern", (
|
||||
([OP_NAME_NEW, OP_DROP, "name", "days", OP_2DROP, -1, OP_DROP],
|
||||
[OP_NAME_NEW, OP_DROP, NAME, DAYS, OP_2DROP, VALUE, OP_DROP]),
|
||||
([OP_NAME_NEW, OP_DROP, "name", OP_DROP, -1, OP_DROP, "days", OP_DROP],
|
||||
[OP_NAME_NEW, OP_DROP, NAME, OP_DROP, VALUE, OP_DROP, DAYS, OP_DROP]),
|
||||
|
||||
([OP_NAME_NEW, OP_DROP, "name", "days", OP_2DROP, DP_MULT],
|
||||
[OP_NAME_NEW, OP_DROP, NAME, DAYS, OP_2DROP, VALUE, OP_DROP]),
|
||||
([OP_NAME_NEW, OP_DROP, "name", "days", OP_2DROP, DP_MULT],
|
||||
[OP_NAME_NEW, OP_DROP, NAME, DAYS, OP_2DROP, VALUE, VALUE, OP_2DROP]),
|
||||
([OP_NAME_NEW, OP_DROP, "name", "days", OP_2DROP, DP_MULT],
|
||||
[OP_NAME_NEW, OP_DROP, NAME, DAYS, OP_2DROP, VALUE, VALUE, VALUE, OP_2DROP, OP_DROP]),
|
||||
|
||||
([OP_NAME_NEW, OP_DROP, "name", OP_2DROP, DP_MULT, "days", OP_DROP],
|
||||
[OP_NAME_NEW, OP_DROP, NAME, OP_2DROP, VALUE, OP_DROP, DAYS, OP_DROP]),
|
||||
([OP_NAME_NEW, OP_DROP, "name", OP_2DROP, DP_MULT, "days", OP_DROP],
|
||||
[OP_NAME_NEW, OP_DROP, NAME, OP_2DROP, VALUE, VALUE, OP_2DROP, DAYS, OP_DROP]),
|
||||
([OP_NAME_NEW, OP_DROP, "name", OP_2DROP, DP_MULT, "days", OP_DROP],
|
||||
[OP_NAME_NEW, OP_DROP, NAME, OP_2DROP, VALUE, VALUE, VALUE, OP_2DROP, OP_DROP, DAYS, OP_DROP]),
|
||||
))
|
||||
def test_name_mixin_interpret_name_prefix_with_named_placeholders(opcode, pattern):
|
||||
ops = [opcode]
|
||||
script = create_script(pattern, ADDRESS_SCRIPT)
|
||||
parsed_names, parsed_address_script = NameMixin.interpret_name_prefix(script, ops)
|
||||
|
||||
assert parsed_names["name"][1] == NAME
|
||||
assert parsed_names["days"][1] == DAYS
|
||||
assert parsed_address_script == ADDRESS_SCRIPT
|
||||
|
||||
|
||||
@pytest.mark.parametrize("opcode", (
|
||||
[OP_NAME_UPDATE, OP_DROP, -1, -1, OP_2DROP, -1, OP_DROP],
|
||||
[OP_NAME_NEW, OP_DROP, -1, -1, OP_DROP, OP_DROP, -1, OP_DROP],
|
||||
[OP_NAME_NEW, OP_DROP, "name", "days", OP_DROP, -1, OP_DROP],
|
||||
))
|
||||
def test_name_mixin_interpret_name_prefix_wrong_ops(opcode):
|
||||
ops = [opcode]
|
||||
script = create_script([OP_NAME_NEW, OP_DROP, NAME, DAYS, OP_2DROP,
|
||||
VALUE, OP_DROP], ADDRESS_SCRIPT)
|
||||
parsed_names, parsed_address_script = NameMixin.interpret_name_prefix(script, ops)
|
||||
|
||||
assert parsed_names is None
|
||||
assert parsed_address_script == script
|
||||
@@ -0,0 +1,49 @@
|
||||
# Tests of server/env.py
|
||||
|
||||
import os
|
||||
|
||||
import pytest
|
||||
|
||||
from electrumx.lib.env_base import EnvBase
|
||||
|
||||
|
||||
os.environ.update({
|
||||
'int': '32',
|
||||
'intspace': ' 32 ',
|
||||
'true': 'x',
|
||||
'false': '',
|
||||
'space': ' ',
|
||||
})
|
||||
|
||||
def test_default():
|
||||
e = EnvBase()
|
||||
assert e.default('int', '33') == '32'
|
||||
assert e.default('baz', 'z') == 'z'
|
||||
|
||||
def test_boolean():
|
||||
e = EnvBase()
|
||||
assert e.boolean('true', False)
|
||||
assert not e.boolean('false', True)
|
||||
assert not e.boolean('space', True)
|
||||
assert e.boolean('missing', True)
|
||||
assert not e.boolean('missing', False)
|
||||
|
||||
def test_required():
|
||||
e = EnvBase()
|
||||
assert e.required('true') == 'x'
|
||||
with pytest.raises(e.Error):
|
||||
e.required('missing')
|
||||
|
||||
def test_integer():
|
||||
e = EnvBase()
|
||||
assert e.integer('int', 33) == 32
|
||||
assert e.integer('missing', 33) == 33
|
||||
assert e.integer('intspace', 33) == 32
|
||||
assert e.integer('missing', None) is None
|
||||
with pytest.raises(e.Error):
|
||||
e.integer('true', 1)
|
||||
|
||||
def test_obsolete():
|
||||
e = EnvBase()
|
||||
with pytest.raises(e.Error):
|
||||
e.obsolete(['z', 'space'])
|
||||
@@ -0,0 +1,74 @@
|
||||
#
|
||||
# Tests of lib/hash.py
|
||||
#
|
||||
from functools import partial
|
||||
|
||||
import pytest
|
||||
|
||||
import electrumx.lib.hash as lib_hash
|
||||
|
||||
|
||||
def test_sha256():
|
||||
assert lib_hash.sha256(b'sha256') == b'][\t\xf6\xdc\xb2\xd5:_\xff\xc6\x0cJ\xc0\xd5_\xab\xdfU`i\xd6c\x15E\xf4*\xa6\xe3P\x0f.'
|
||||
with pytest.raises(TypeError):
|
||||
lib_hash.sha256('sha256')
|
||||
|
||||
def test_double_sha256():
|
||||
assert lib_hash.double_sha256(b'double_sha256') == b'ksn\x8e\xb7\xb9\x0f\xf6\xd9\xad\x88\xd9#\xa1\xbcU(j1Bx\xce\xd5;s\xectL\xe7\xc5\xb4\x00'
|
||||
|
||||
def test_hash_to_hex_str():
|
||||
assert lib_hash.hash_to_hex_str(b'hash_to_str') == '7274735f6f745f68736168'
|
||||
|
||||
def test_hex_str_to_hash():
|
||||
assert lib_hash.hex_str_to_hash('7274735f6f745f68736168') == b'hash_to_str'
|
||||
|
||||
def test_Base58_char_value():
|
||||
chars = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
|
||||
for value, c in enumerate(chars):
|
||||
assert lib_hash.Base58.char_value(c) == value
|
||||
for c in (' ', 'I', '0', 'l', 'O'):
|
||||
with pytest.raises(lib_hash.Base58Error):
|
||||
lib_hash.Base58.char_value(c)
|
||||
|
||||
def test_Base58_decode():
|
||||
with pytest.raises(TypeError):
|
||||
lib_hash.Base58.decode(b'foo')
|
||||
with pytest.raises(lib_hash.Base58Error):
|
||||
lib_hash.Base58.decode('')
|
||||
assert lib_hash.Base58.decode('123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz') == b'\x00\x01\x11\xd3\x8e_\xc9\x07\x1f\xfc\xd2\x0bJv<\xc9\xaeO%+\xb4\xe4\x8f\xd6j\x83^%*\xda\x93\xffH\rm\xd4=\xc6*d\x11U\xa5'
|
||||
assert lib_hash.Base58.decode('3i37NcgooY8f1S') == b'0123456789'
|
||||
|
||||
def test_Base58_encode():
|
||||
with pytest.raises(TypeError):
|
||||
lib_hash.Base58.encode('foo')
|
||||
assert lib_hash.Base58.encode(b'') == ''
|
||||
assert lib_hash.Base58.encode(b'\0') == '1'
|
||||
assert lib_hash.Base58.encode(b'0123456789') == '3i37NcgooY8f1S'
|
||||
|
||||
def test_Base58_decode_check():
|
||||
with pytest.raises(TypeError):
|
||||
lib_hash.Base58.decode_check(b'foo')
|
||||
assert lib_hash.Base58.decode_check('4t9WKfuAB8') == b'foo'
|
||||
with pytest.raises(lib_hash.Base58Error):
|
||||
lib_hash.Base58.decode_check('4t9WKfuAB9')
|
||||
|
||||
def test_Base58_encode_check():
|
||||
with pytest.raises(TypeError):
|
||||
lib_hash.Base58.encode_check('foo')
|
||||
assert lib_hash.Base58.encode_check(b'foo') == '4t9WKfuAB8'
|
||||
|
||||
def test_Base58_decode_check_custom():
|
||||
decode_check_sha256 = partial(lib_hash.Base58.decode_check,
|
||||
hash_fn=lib_hash.sha256)
|
||||
with pytest.raises(TypeError):
|
||||
decode_check_sha256(b'foo')
|
||||
assert decode_check_sha256('4t9WFhKfWr') == b'foo'
|
||||
with pytest.raises(lib_hash.Base58Error):
|
||||
decode_check_sha256('4t9WFhKfWp')
|
||||
|
||||
def test_Base58_encode_check_custom():
|
||||
encode_check_sha256 = partial(lib_hash.Base58.encode_check,
|
||||
hash_fn=lib_hash.sha256)
|
||||
with pytest.raises(TypeError):
|
||||
encode_check_sha256('foo')
|
||||
assert encode_check_sha256(b'foo') == '4t9WFhKfWr'
|
||||
@@ -0,0 +1,280 @@
|
||||
import os
|
||||
import pytest
|
||||
|
||||
from electrumx.lib.merkle import Merkle, MerkleCache
|
||||
|
||||
|
||||
merkle = Merkle()
|
||||
hashes = [merkle.hash_func(bytes([x])) for x in range(8)]
|
||||
roots = [
|
||||
b'\x14\x06\xe0X\x81\xe2\x996wf\xd3\x13\xe2l\x05VN\xc9\x1b\xf7!\xd3\x17&\xbdnF\xe6\x06\x89S\x9a',
|
||||
b'K\xbe\x83\xbc8\xeb\xe2\xbc\xc7R\r#A9\xdf\x1c\x0e\xb9\xff\xa5\x1f\x83\xea\xb1\xc5\x12\x9b[\x90kvU',
|
||||
b'\xe1)\xdf\xe0/V\x7f\xc6\x12\xd1&YmC@aD\xf4\nw\x18\x10\xacqCB\x1d-\xf3\xe5\xc1\xd0',
|
||||
b'\xe3/W\x01\xa0\x11Z+M\xc7/Rj\xf1aLY,\x19\xee\x95\xcf\xcb\x055\x96\x1e\x07g\xba\xf7\x8e',
|
||||
b'\xf4\x118I\xd6(\xf7\xc3\xbc\x91\xcc\x0f\xf7\x85\xa6\xae\xe3\xee#l\x1c\x91+(\xcc\t\xc4O\x9f\x97\xb7H',
|
||||
b'\xfb[\xb7\xe4\x82Y"\xea\xe8\xc2\xba\xec\x96\x0c\x8fR3\x84R"\x13Jj=\x84\x0e<\x12\x01\xafu\xed',
|
||||
b'}\xe6\\}W\xcd\xc7)q\xc9\xbe\xab\x94\xafj\xd4\xe9\x9f#?\xb6\xcc\xeb\xd2\xb4\xb1\x9f\x13i|\xa5M',
|
||||
b'o\x97(*\xb3G\xa2e\xae3\x83\xe1V\x9eb\xda\x8c\x19\xa6\x8c\xfag\r+az\x7f\xedGD\xbb\xfe'
|
||||
]
|
||||
|
||||
|
||||
|
||||
def test_branch_length():
|
||||
assert merkle.branch_length(1) == 0
|
||||
assert merkle.branch_length(2) == 1
|
||||
for n in range(3, 5):
|
||||
assert merkle.branch_length(n) == 2
|
||||
for n in range(5, 9):
|
||||
assert merkle.branch_length(n) == 3
|
||||
|
||||
|
||||
def test_branch_length_bad():
|
||||
with pytest.raises(TypeError):
|
||||
merkle.branch_length(1.0)
|
||||
for n in (-1, 0):
|
||||
with pytest.raises(ValueError):
|
||||
merkle.branch_length(n)
|
||||
|
||||
|
||||
def test_tree_depth():
|
||||
for n in range(1, 10):
|
||||
assert merkle.tree_depth(n) == merkle.branch_length(n) + 1
|
||||
|
||||
|
||||
def test_root():
|
||||
for n in range(len(hashes)):
|
||||
assert merkle.root(hashes[:n + 1]) == roots[n]
|
||||
|
||||
|
||||
def test_root_bad():
|
||||
with pytest.raises(TypeError):
|
||||
merkle.root(0)
|
||||
with pytest.raises(ValueError):
|
||||
merkle.root([])
|
||||
|
||||
|
||||
def test_branch_and_root_from_proof():
|
||||
for n in range(len(hashes)):
|
||||
for m in range(n + 1):
|
||||
branch, root = merkle.branch_and_root(hashes[:n + 1], m)
|
||||
assert root == roots[n]
|
||||
root = merkle.root_from_proof(hashes[m], branch, m)
|
||||
assert root == roots[n]
|
||||
|
||||
|
||||
def test_branch_bad():
|
||||
with pytest.raises(TypeError):
|
||||
merkle.branch_and_root(0, 0)
|
||||
with pytest.raises(ValueError):
|
||||
merkle.branch_and_root([], 0)
|
||||
with pytest.raises(TypeError):
|
||||
merkle.branch_and_root(hashes, 0.0)
|
||||
with pytest.raises(ValueError):
|
||||
merkle.branch_and_root(hashes[:2], -1)
|
||||
with pytest.raises(ValueError):
|
||||
merkle.branch_and_root(hashes[:2], 2)
|
||||
merkle.branch_and_root(hashes, 0, 3)
|
||||
with pytest.raises(TypeError):
|
||||
merkle.branch_and_root(hashes, 0, 3.0)
|
||||
with pytest.raises(ValueError):
|
||||
merkle.branch_and_root(hashes, 0, 2)
|
||||
|
||||
|
||||
def test_root_from_proof_bad():
|
||||
with pytest.raises(TypeError):
|
||||
merkle.root_from_proof(0, hashes[:2], 0)
|
||||
with pytest.raises(TypeError):
|
||||
merkle.root_from_proof(hashes[0], hashes[0], 0)
|
||||
with pytest.raises(ValueError):
|
||||
merkle.root_from_proof(hashes[0], hashes[:3], -1)
|
||||
with pytest.raises(ValueError):
|
||||
merkle.root_from_proof(hashes[0], hashes[:3], 8)
|
||||
|
||||
|
||||
def test_level():
|
||||
for n in range(len(hashes)):
|
||||
depth = merkle.tree_depth(n + 1)
|
||||
for depth_higher in range(0, depth):
|
||||
level = merkle.level(hashes[:n + 1], depth_higher)
|
||||
if depth_higher == 0:
|
||||
assert level == hashes[:n + 1]
|
||||
if depth_higher == depth:
|
||||
assert level == [roots[n]]
|
||||
# Check raising from level to root works
|
||||
assert merkle.root(level) == roots[n]
|
||||
|
||||
|
||||
def test_branch_and_root_from_level():
|
||||
# For all sub-trees
|
||||
for n in range(0, len(hashes)):
|
||||
part = hashes[:n + 1]
|
||||
# For all depths in sub-tree
|
||||
for depth_higher in range(0, merkle.tree_depth(len(part))):
|
||||
level = merkle.level(part, depth_higher)
|
||||
# For each hash in sub-tree
|
||||
for index, hash in enumerate(part):
|
||||
leaf_index = (index >> depth_higher) << depth_higher
|
||||
leaf_hashes = part[leaf_index:
|
||||
leaf_index + (1 << depth_higher)]
|
||||
branch = merkle.branch_and_root(part, index)
|
||||
branch2 = merkle.branch_and_root_from_level(
|
||||
level, leaf_hashes, index, depth_higher)
|
||||
assert branch == branch2
|
||||
|
||||
|
||||
def test_branch_and_root_from_level_bad():
|
||||
with pytest.raises(TypeError):
|
||||
merkle.branch_and_root_from_level(hashes[0], hashes, 0, 0)
|
||||
with pytest.raises(TypeError):
|
||||
merkle.branch_and_root_from_level(hashes, hashes[0], 0, 0)
|
||||
merkle.branch_and_root_from_level(hashes, [hashes[0]], 0, 0)
|
||||
with pytest.raises(ValueError):
|
||||
merkle.branch_and_root_from_level(hashes, [hashes[0]], -1, 0)
|
||||
with pytest.raises(TypeError):
|
||||
merkle.branch_and_root_from_level(hashes, hashes, 0.0, 0)
|
||||
with pytest.raises(ValueError):
|
||||
merkle.branch_and_root_from_level(hashes, [hashes[0]], 0, -1)
|
||||
with pytest.raises(ValueError):
|
||||
merkle.branch_and_root_from_level(hashes, [hashes[0]], 0, 1)
|
||||
with pytest.raises(ValueError):
|
||||
# Inconsistent hash
|
||||
merkle.branch_and_root_from_level(hashes, [hashes[1]], 0, 0)
|
||||
with pytest.raises(ValueError):
|
||||
# Inconsistent hash
|
||||
merkle.branch_and_root_from_level(hashes, [hashes[0]], 1, 0)
|
||||
|
||||
|
||||
class Source:
|
||||
|
||||
def __init__(self, length):
|
||||
self._hashes = [os.urandom(32) for _ in range(length)]
|
||||
|
||||
async def hashes(self, start, count):
|
||||
assert start >= 0
|
||||
assert start + count <= len(self._hashes)
|
||||
return self._hashes[start: start + count]
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_merkle_cache():
|
||||
lengths = (*range(1, 18), 31, 32, 33, 57)
|
||||
source = Source(max(lengths)).hashes
|
||||
for length in lengths:
|
||||
cache = MerkleCache(merkle, source)
|
||||
await cache.initialize(length)
|
||||
# Simulate all possible checkpoints
|
||||
for cp_length in range(1, length + 1):
|
||||
cp_hashes = await source(0, cp_length)
|
||||
# All possible indices
|
||||
for index in range(cp_length):
|
||||
# Compare correct answer with cache
|
||||
branch, root = merkle.branch_and_root(cp_hashes, index)
|
||||
branch2, root2 = await cache.branch_and_root(cp_length, index)
|
||||
assert branch == branch2
|
||||
assert root == root2
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_merkle_cache_extension():
|
||||
source = Source(64).hashes
|
||||
for length in range(14, 18):
|
||||
for cp_length in range(30, 36):
|
||||
cache = MerkleCache(merkle, source)
|
||||
await cache.initialize(length)
|
||||
cp_hashes = await source(0, cp_length)
|
||||
# All possible indices
|
||||
for index in range(cp_length):
|
||||
# Compare correct answer with cache
|
||||
branch, root = merkle.branch_and_root(cp_hashes, index)
|
||||
branch2, root2 = await cache.branch_and_root(cp_length, index)
|
||||
assert branch == branch2
|
||||
assert root == root2
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_merkle_cache_truncation():
|
||||
max_length = 33
|
||||
source = Source(max_length).hashes
|
||||
for length in range(max_length - 2, max_length + 1):
|
||||
for trunc_length in range(1, 20, 3):
|
||||
cache = MerkleCache(merkle, source)
|
||||
await cache.initialize(length)
|
||||
cache.truncate(trunc_length)
|
||||
assert cache.length <= trunc_length
|
||||
for cp_length in range(1, length + 1, 3):
|
||||
cp_hashes = await source(0, cp_length)
|
||||
# All possible indices
|
||||
for index in range(cp_length):
|
||||
# Compare correct answer with cache
|
||||
branch, root = merkle.branch_and_root(cp_hashes, index)
|
||||
branch2, root2 = await cache.branch_and_root(cp_length,
|
||||
index)
|
||||
assert branch == branch2
|
||||
assert root == root2
|
||||
|
||||
# Truncation is a no-op if longer
|
||||
cache = MerkleCache(merkle, source)
|
||||
await cache.initialize(10)
|
||||
level = cache.level.copy()
|
||||
for length in range(10, 13):
|
||||
cache.truncate(length)
|
||||
assert cache.level == level
|
||||
assert cache.length == 10
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_truncation_bad():
|
||||
cache = MerkleCache(merkle, Source(10).hashes)
|
||||
await cache.initialize(10)
|
||||
with pytest.raises(TypeError):
|
||||
cache.truncate(1.0)
|
||||
for n in (-1, 0):
|
||||
with pytest.raises(ValueError):
|
||||
cache.truncate(n)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_merkle_cache_bad():
|
||||
length = 23
|
||||
source = Source(length).hashes
|
||||
cache = MerkleCache(merkle, source)
|
||||
await cache.initialize(length)
|
||||
await cache.branch_and_root(5, 3)
|
||||
with pytest.raises(TypeError):
|
||||
await cache.branch_and_root(5.0, 3)
|
||||
with pytest.raises(TypeError):
|
||||
await cache.branch_and_root(5, 3.0)
|
||||
with pytest.raises(ValueError):
|
||||
await cache.branch_and_root(0, -1)
|
||||
with pytest.raises(ValueError):
|
||||
await cache.branch_and_root(3, 3)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_bad_extension():
|
||||
length = 5
|
||||
source = Source(length).hashes
|
||||
cache = MerkleCache(merkle, source)
|
||||
await cache.initialize(length)
|
||||
level = cache.level.copy()
|
||||
with pytest.raises(AssertionError):
|
||||
await cache.branch_and_root(8, 0)
|
||||
# The bad extension should not destroy the cache
|
||||
assert cache.level == level
|
||||
assert cache.length == length
|
||||
|
||||
|
||||
async def time_it():
|
||||
source = Source(500000).hashes
|
||||
cp_length = 492000
|
||||
import time
|
||||
cache = MerkleCache(merkle, source)
|
||||
await cache.initialize(cp_length)
|
||||
cp_hashes = await source(0, cp_length)
|
||||
brs2 = []
|
||||
t1 = time.monotonic()
|
||||
for index in range(5, 400000, 500):
|
||||
brs2.append(await cache.branch_and_root(cp_length, index))
|
||||
t2 = time.monotonic()
|
||||
print(t2 - t1)
|
||||
assert False
|
||||
@@ -0,0 +1,26 @@
|
||||
import pytest
|
||||
|
||||
from electrumx.lib.script import OpCodes, is_unspendable_legacy, is_unspendable_genesis
|
||||
|
||||
|
||||
@pytest.mark.parametrize("script, iug", (
|
||||
(bytes([OpCodes.OP_RETURN]), False),
|
||||
(bytes([OpCodes.OP_RETURN]) + bytes([2, 28, 50]), False),
|
||||
(bytes([OpCodes.OP_0, OpCodes.OP_RETURN]), True),
|
||||
(bytes([OpCodes.OP_0, OpCodes.OP_RETURN]) + bytes([2, 28, 50]), True)
|
||||
))
|
||||
def test_op_return_legacy(script, iug):
|
||||
assert is_unspendable_legacy(script)
|
||||
assert is_unspendable_genesis(script) is iug
|
||||
|
||||
|
||||
@pytest.mark.parametrize("script", (
|
||||
bytes([]),
|
||||
bytes([OpCodes.OP_1, OpCodes.OP_RETURN]) + bytes([2, 28, 50]),
|
||||
bytes([OpCodes.OP_0]),
|
||||
bytes([OpCodes.OP_0, OpCodes.OP_1]),
|
||||
bytes([OpCodes.OP_HASH160]),
|
||||
))
|
||||
def test_not_op_return(script):
|
||||
assert not is_unspendable_legacy(script)
|
||||
assert not is_unspendable_genesis(script)
|
||||
@@ -0,0 +1,37 @@
|
||||
import electrumx.lib.tx as tx_lib
|
||||
|
||||
tests = [
|
||||
"020000000192809f0b234cb850d71d020e678e93f074648ed0df5affd0c46d3bcb177f"
|
||||
"9ccf020000008b483045022100c5403bcf86c3ae7b8fd4ca0d1e4df6729cc1af05ff95"
|
||||
"d9726b43a64b41dd5d9902207fab615f41871885aa3062fc7d8f8d9d3dcbc2e4867c5d"
|
||||
"96dd7a176b99e927924141040baa4271a82c5f1a09a5ea63d763697ca0545b6049c4dd"
|
||||
"8e8d099dd91f2da10eb11e829000a82047ac56969fb582433067a21c3171e569d1832c"
|
||||
"34fdd793cfc8ffffffff030000000000000000226a20195ce612d20e5284eb78bb28c9"
|
||||
"c50d6139b10b77b2d5b2f94711b13162700472bfc53000000000001976a9144a519c63"
|
||||
"f985ba5ab8b71bb42f1ecb82a0a0d80788acf6984315000000001976a9148b80536aa3"
|
||||
"c460258cda834b86a46787c9a2b0bf88ac00000000",
|
||||
"0200000003ee933f16c93d433bfd45426e94ddb4c0406aecac66f1c23a9e55151430c2"
|
||||
"b4c4a70000006b483045022100c940624ddbefcf86f3a3d820347de9c695204583a3ce"
|
||||
"9977c45cb1d6f69d577202205e0d9e9c0bfc2993160edad71cd1474b6308d990a89a54"
|
||||
"c80d7c62295edd2a394121039999e7c52a1447916b2af30478669c4e6e3ce52b895da7"
|
||||
"78f0b46b73f8ea6f00feffffff30be91ac83fee19e06304732027a39f9ec9018c5aae1"
|
||||
"159bf1c5de53dea61785fc0200006a473044022057cee17c3e123864336bdd6373e4bc"
|
||||
"0bf030ca70dd078520705930a4168610d0022061fdeedfbeb0b89c3b20db220799978b"
|
||||
"c94e11e4155b810b8b59df019b3f1859412103e2074e4387eeb3b1dec2fc8b953b0c13"
|
||||
"c53d0d3b7b676e1b3ca75ee606ecf750feffffffdd462d60e51be69451f06c36ba4490"
|
||||
"aaad8ebf40501dd27341e9c64a5f633324000000006a473044022043511ab874f0037c"
|
||||
"5726b1efc69fcdb638fac74ab3f6766eb80947cff8c1175a02200606ccf8db60f56e77"
|
||||
"03f6d5b81f5f5141f5b029a7b5a35700907f368b7e0f024121038daab4c77b9a428efb"
|
||||
"23aa2ccadc5c5332f299f5e51d1f1600524c0313ab9ec2feffffff04fe66c200000000"
|
||||
"001976a914a8c27c62fafec0a07d28b3b905912e9f385a7f1a88ac2a3b560800000000"
|
||||
"1976a914c20992e92764ef7e33e2cf6ed538d34b18a1fff888ac00a3e1110000000019"
|
||||
"76a9147137cd9dc7aad0d1cbc8e0ec12aae753d1acfaf488ac5d2b0f00000000001976"
|
||||
"a914c10084f449e968b0d71ee23a308954c68d8c97e488ac28620700"
|
||||
]
|
||||
|
||||
def test_tx_serialiazation():
|
||||
for test in tests:
|
||||
test = bytes.fromhex(test)
|
||||
deser = tx_lib.Deserializer(test)
|
||||
tx = deser.read_tx()
|
||||
assert tx.serialize() == test
|
||||
@@ -0,0 +1,402 @@
|
||||
import pytest
|
||||
|
||||
import electrumx.lib.tx_axe as lib_tx_axe
|
||||
|
||||
|
||||
bfh = bytes.fromhex
|
||||
|
||||
|
||||
V2_TX = (
|
||||
'020000000192809f0b234cb850d71d020e678e93f074648ed0df5affd0c46d3bcb177f'
|
||||
'9ccf020000008b483045022100c5403bcf86c3ae7b8fd4ca0d1e4df6729cc1af05ff95'
|
||||
'd9726b43a64b41dd5d9902207fab615f41871885aa3062fc7d8f8d9d3dcbc2e4867c5d'
|
||||
'96dd7a176b99e927924141040baa4271a82c5f1a09a5ea63d763697ca0545b6049c4dd'
|
||||
'8e8d099dd91f2da10eb11e829000a82047ac56969fb582433067a21c3171e569d1832c'
|
||||
'34fdd793cfc8ffffffff030000000000000000226a20195ce612d20e5284eb78bb28c9'
|
||||
'c50d6139b10b77b2d5b2f94711b13162700472bfc53000000000001976a9144a519c63'
|
||||
'f985ba5ab8b71bb42f1ecb82a0a0d80788acf6984315000000001976a9148b80536aa3'
|
||||
'c460258cda834b86a46787c9a2b0bf88ac00000000')
|
||||
|
||||
|
||||
CB_TX = ( '03000500010000000000000000000000000000000000000000000000000000000000000000ffffffff1303c407040e2f5032506f6f6c2d74444153482fffffffff0448d6a73d000000001976a914293859173a34194d445c2962b97383e2a93d7cb288ac22fc433e000000001976a914bf09c602c6b8f1db246aba5c37ad1cfdcb16b15e88ace9259c00000000004341047559d13c3f81b1fadbd8dd03e4b5a1c73b05e2b980e00d467aa9440b29c7de23664dde6428d75cafed22ae4f0d302e26c5c5a5dd4d3e1b796d7281bdc9430f35ac00000000000000002a6a28be61411c3c79b7fd45923118ba74d340afb248ae2edafe78c15e2d1aa337c942000000000000000000000000260100c407040076629a6e42fb519188f65889fd3ac0201be87aa227462b5643e8bb2ec1d7a82a')
|
||||
|
||||
CB_TX_V2 = ( '03000500010000000000000000000000000000000000000000000000000000000000000000ffffffff2603caac04194d696e656420627920416e74506f6f6c52000b03203e009e9457070000441a0000ffffffff02db98d40b000000001976a9141d16d67366c081e6cc6b402667fa8044c4a42e8888ac9d65130d000000001976a9146ca3b3578583b5c73adb302ccb612b9a5fbef17488ac00000000460200caac04002d126055d9cd81da35972dd5f11d8b7d24d23beeb9331d64d93ca74966fff9120000000000000000000000000000000000000000000000000000000000000000')
|
||||
|
||||
PRO_REG_TX = ( '03000100013a196f2a59b88dcbadb48b580dd4ef14f6d1dd6f86e8d6cb8942c34837a45448000000006a473044022048b0c1703e7c40750097d770b5f05b8ccdd5a656d24970fd769712830404958702205c63c57cdba86026a0fd58dc7633eb0ae6f66ef43e96915c3b74bb4c7747a885012103542c5d737685944600d238ae5e6abc7e2906e34453d6af5a0fadd84dd8e09242feffffff0121c89a3b000000001976a91435af662851170d5ddebba4e287019a4597dd453d88ac00000000fd12010100000000002181625260614470c020764d56d7a2eb9bedb0a2f65f0168c99a4fdf846573910000000000000000000000000000ffff74cb7f7f26d1c1a9c6453135e83be71635ac840652bbefc607861908c153792530dfe635bdf819ceb7963b624233a3465be94a4651ca36f7c0917d301c1e61485b68debc2f9fe5b7e84bc1a9c6453135e83be71635ac840652bbefc6078600001976a914950c9dea79cee4c4fea859c95fd534bba21f9a3088acf3a95bbe35ccdbe9d8cd3a875e3f80af725422bcf44d35ce79078df357c29bf9412088b70bd05dbbd5a86d51abc78e33658f95ac01b98bc16dd537bcac5c48d3db437ee6c9b1d664e2a192b64b1893b3ce22b4ac47da9c4a0d148440be74527a43d4' )
|
||||
|
||||
PRO_UP_SERV_TX = ( '0300020001423cef3af2b56378737de6bf9d1a5055f07bd35d86585770ce0449c7d5062f0a010000006a473044022013390c4c6f4411cbaee91ea49bb12c29b9618f4902c522274b013c5c20f81f77022022cc2ebb97aed1eecaaad17c9dbd4ad0f42a2969e4599f8e4214a008cd51b9f20121034125651548c482a003fb59229898169e8d289b84dc48f6dfbe160c08bfcec144feffffff01fa294209000000001976a914f489af78bc73074aee98082d2876d710aa242e6188ac00000000b50100bef73450cab0889367710dd4ccd80cdb47557ad135dcb0e54f2cd8b9623cd57300000000000000000000ffff2d3f1f37270f00768450381dca4e9888aa7be9a7725e0824696fc24f5a35de62916dc81b3085b3077e02247c17992ba5ee9a2894e03c2e489b07cb9b751207dd51ca5c3dc6b67bada8f82a41c3137dbb203ce185caaccf1565e62c626e5225ff741e01faf4b09d8d7300dfb5c3e6f352120047b2e7b0547e5ea1198b615bf4826eaba252f97007' )
|
||||
|
||||
PRO_UP_REG_TX = ( '030003000114b05579c72dc0785130153c35c8e398fcf1c49594800707b42e8beb73e5d76d000000006b483045022100b13e220d2bf1633002cb9d94f33f5bbf974ea0c4380d4497fedad2c422d92fde0220166f6894eb8e778d55f7b86089fd4ef08e481bb4f04bff67ea2bcb07c5dc2cba012102e2f8099a84f13f9e8e5d784567d49df919ec63764966738df83371c66ff534f6feffffff011f320f00000000001976a914bcc00fdff28f1b7b85ec5135b7a2d8c800a5c01888ac00000000e40100454bce26dde61cce5a8190928ed2af0f95c5bc053c88170b1a653028b36a29a300008aba2efc6ef0305e8aadb650a5e5e15f7ea583968b48ea47bcec4bfaab108aa98f2e4ed0bb66946f7b65dff9ee92820dc99a89fcafd3a4729860b2f9cd2ba4a7d965e9271976a9148e124bfba342a13dec4d7a932284179a7f9c9e6188acd2972fcc5557d534cc6a9ed494e6213673521dbccacf4d3637994a5aaad721d34120697182d7c398d4add6c49f0ddc7e71ec0253f0ff0d198b23913f8231ff18140f0b880feed08c267b0e9c70d9136c028c6126f7ae014879442b93c3a538ee6ac6' )
|
||||
|
||||
PRO_UP_REV_TX = ( '0300040001fb9e4b60ee4c625820b52f20067e1f7ce652526f3834afe334b010eddf1ac4e8000000006a47304402203386143fa1e39df1936fcc2af593837f9c815deb04440bfc9b877790e4caff4202202cdb7895a9656d3e62dc8ec2eada1de6d3b11acd517ab09c46ec274698cdefd7012103e10e8542bc703af92dc7c66a4a471f8101472b1a37b83a01309227ad2f7ebf14feffffff017b0d0b00000000001976a91493b17c6f50f75069b93864675c7cb1e9b9dbf3cf88ac00000000a40100d1061c3f0f32e332f100f153041797eebd2702a5f419d2d057023f7f7238c922030041a7d06f62ec60981969414d738489e4a0d8d4dcfb74e8a1ad2182f4e3de97d90e4222e82aa968d8d1c6fda6a553d6071897c8985fda438922d773b7aeabdbaa22cb699b248c0e15bfd7b52e230920ab04ac4881aaffe836bfbc53c6e95671ede9a8185fceece5b3ce1480a824a67fd004a15a2bb34fabb82688344d0b6d2669' )
|
||||
|
||||
''' No DIP0005 in Axe for Now
|
||||
SUB_TX_REGISTER = (
|
||||
'03000800010931c6b0ad7ce07f3c8aefeeb78e246a4fe6872bbf08ab6e4eb6a7b69acd'
|
||||
'64a6010000006b483045022100a2feb698c43c752738fabea281b7e9e5a3aa648a4c54'
|
||||
'1171e06d7c372db92c65022061c1ec3c92f2e76bb7fb1b548d854f19a41e6421267231'
|
||||
'74150412caf3e98e9601210293360bf2a2e810673412bc6e8e0e358f3fb7bdbe9a667b'
|
||||
'3d0103f761cc69a211feffffff0189fa433e000000001976a914551ab8ca96a9142217'
|
||||
'4d22769c3a4f90b2dcd0de88ac00000000960100036162638e7042ec88acefcfe3d578'
|
||||
'914bb48c6bd71b3459d384e42374e8abfeffffff01570b0000000000001976a91490c5'
|
||||
'ce9d8bc992a88ac00000000a40100b67ffbbd095de31ea38446754e8abfeffffff0157'
|
||||
'0b0000000000001976a91490c5ce9d8bc992a88ac00000000a40100b67ffbbd095de31'
|
||||
'ea38446754e8abfeffffff01570b0000000000001976a91490c5ce9d')
|
||||
|
||||
|
||||
SUB_TX_TOPUP = (
|
||||
'03000900010931c6b0ad7ce07f3c8aefeeb78e246a4fe6872bbf08ab6e4eb6a7b69acd'
|
||||
'64a6010000006b483045022100a2feb698c43c752738fabea281b7e9e5a3aa648a4c54'
|
||||
'1171e06d7c372db92c65022061c1ec3c92f2e76bb7fb1b548d854f19a41e6421267231'
|
||||
'74150412caf3e98e9601210293360bf2a2e810673412bc6e8e0e358f3fb7bdbe9a667b'
|
||||
'3d0103f761cc69a211feffffff0189fa433e000000001976a914551ab8ca96a9142217'
|
||||
'4d22769c3a4f90b2dcd0de88ac00000000220100d384e42374e8abfeffffff01570b00'
|
||||
'0000a40100b67ffbbd095de31ea3844675')
|
||||
|
||||
|
||||
SUB_TX_RESET_KEY = (
|
||||
'03000a00010931c6b0ad7ce07f3c8aefeeb78e246a4fe6872bbf08ab6e4eb6a7b69acd'
|
||||
'64a6010000006b483045022100a2feb698c43c752738fabea281b7e9e5a3aa648a4c54'
|
||||
'1171e06d7c372db92c65022061c1ec3c92f2e76bb7fb1b548d854f19a41e6421267231'
|
||||
'74150412caf3e98e9601210293360bf2a2e810673412bc6e8e0e358f3fb7bdbe9a667b'
|
||||
'3d0103f761cc69a211feffffff0189fa433e000000001976a914551ab8ca96a9142217'
|
||||
'4d22769c3a4f90b2dcd0de88ac00000000da0100d384e42374e8abfeffffff01570b00'
|
||||
'0000a40100b67ffbbd095de31ea3844675af3e98e9601210293360bf2a2e810673412b'
|
||||
'c6e8e0e358f3fb7bdbe9a667b3d0e803000000000000601210293360bf2a2e81067341'
|
||||
'2bc6e8e0e358f3fb7bdbe9a667b3d0103f761caf3e98e9601210293360bf2a2e810673'
|
||||
'412bc6e8e0e358f3fb7bdbe9a667b3d0103f761caf3e98e9601210293360bf2a2e8106'
|
||||
'73412bc6e8e0e358f3fb7bdbe9a667b3d0103f761caf3e98e9601210293360bf2a2e81'
|
||||
'0673412bc6e8e0e358f3fb7bdbe9a667b3d0103f761cabcdefab')
|
||||
|
||||
|
||||
SUB_TX_CLOSE_ACCOUNT = (
|
||||
'03000b00010931c6b0ad7ce07f3c8aefeeb78e246a4fe6872bbf08ab6e4eb6a7b69acd'
|
||||
'64a6010000006b483045022100a2feb698c43c752738fabea281b7e9e5a3aa648a4c54'
|
||||
'1171e06d7c372db92c65022061c1ec3c92f2e76bb7fb1b548d854f19a41e6421267231'
|
||||
'74150412caf3e98e9601210293360bf2a2e810673412bc6e8e0e358f3fb7bdbe9a667b'
|
||||
'3d0103f761cc69a211feffffff0189fa433e000000001976a914551ab8ca96a9142217'
|
||||
'4d22769c3a4f90b2dcd0de88ac00000000aa0100d384e42374e8abfeffffff01570b00'
|
||||
'0000a40100b67ffbbd095de31ea3844675af3e98e9601210293360bf2a2e810673412b'
|
||||
'c6e8e0e358f3fb7bdbe9a12bc6e8e803000000000000a62bc6e8e0e358f3fb7bdbe9a6'
|
||||
'67b3d0103f761caf3e98e9601210293360bf2a2e810673412bc6e8e0e358f3fb7bdbe9'
|
||||
'a667b3d0103f761caf3e98e9601210293360bf2a2e810673412bc6e8e0e358f3fb7bdb'
|
||||
'e9a667b3d0103f761cabcdefab')
|
||||
'''
|
||||
|
||||
UNKNOWN_SPEC_TX = (
|
||||
'0300bb00010931c6b0ad7ce07f3c8aefeeb78e246a4fe6872bbf08ab6e4eb6a7b69acd'
|
||||
'64a6010000006b483045022100a2feb698c43c752738fabea281b7e9e5a3aa648a4c54'
|
||||
'1171e06d7c372db92c65022061c1ec3c92f2e76bb7fb1b548d854f19a41e6421267231'
|
||||
'74150412caf3e98e9601210293360bf2a2e810673412bc6e8e0e358f3fb7bdbe9a667b'
|
||||
'3d0103f761cc69a211feffffff0189fa433e000000001976a914551ab8ca96a9142217'
|
||||
'4d22769c3a4f90b2dcd0de88ac00000000aa0100d384e42374e8abfeffffff01570b00'
|
||||
'0000a40100b67ffbbd095de31ea3844675af3e98e9601210293360bf2a2e810673412b'
|
||||
'c6e8e0e358f3fb7bdbe9a12bc6e8e0e358f3fb7bdbe9a62bc6e8e0e358f3fb7bdbe9a6'
|
||||
'67b3d0103f761caf3e98e9601210293360bf2a2e810673412bc6e8e0e358f3fb7bdbe9'
|
||||
'a667b3d0103f761caf3e98e9601210293360bf2a2e810673412bc6e8e0e358f3fb7bdb'
|
||||
'e9a667b3d0103f761cabcdefab')
|
||||
|
||||
|
||||
WRONG_SPEC_TX = ( # Tx version < 3
|
||||
'0200bb00010931c6b0ad7ce07f3c8aefeeb78e246a4fe6872bbf08ab6e4eb6a7b69acd'
|
||||
'64a6010000006b483045022100a2feb698c43c752738fabea281b7e9e5a3aa648a4c54'
|
||||
'1171e06d7c372db92c65022061c1ec3c92f2e76bb7fb1b548d854f19a41e6421267231'
|
||||
'74150412caf3e98e9601210293360bf2a2e810673412bc6e8e0e358f3fb7bdbe9a667b'
|
||||
'3d0103f761cc69a211feffffff0189fa433e000000001976a914551ab8ca96a9142217'
|
||||
'4d22769c3a4f90b2dcd0de88ac00000000')
|
||||
|
||||
|
||||
def test_axe_v2_tx():
|
||||
test = bfh(V2_TX)
|
||||
deser = lib_tx_axe.DeserializerAxe(test)
|
||||
tx = deser.read_tx()
|
||||
assert tx.version == 2
|
||||
assert tx.tx_type == 0
|
||||
assert tx.extra_payload == b''
|
||||
ser = tx.serialize()
|
||||
assert ser == test
|
||||
|
||||
|
||||
def test_axe_tx_cb_tx():
|
||||
test = bfh(CB_TX)
|
||||
deser = lib_tx_axe.DeserializerAxe(test)
|
||||
tx = deser.read_tx()
|
||||
assert tx.version == 3
|
||||
assert tx.tx_type == 5
|
||||
extra = tx.extra_payload
|
||||
assert extra.version == 1
|
||||
assert extra.height == 264132
|
||||
assert len(extra.merkleRootMNList) == 32
|
||||
assert extra.merkleRootMNList == bfh(
|
||||
'76629a6e42fb519188f65889fd3ac0201be87aa227462b5643e8bb2ec1d7a82a')
|
||||
ser = tx.serialize()
|
||||
assert ser == test
|
||||
|
||||
|
||||
def test_axe_tx_cb_tx_v2():
|
||||
test = bfh(CB_TX_V2)
|
||||
deser = lib_tx_axe.DeserializerAxe(test)
|
||||
tx = deser.read_tx()
|
||||
assert tx.version == 3
|
||||
assert tx.tx_type == 5
|
||||
extra = tx.extra_payload
|
||||
assert extra.version == 2
|
||||
assert extra.height == 306378
|
||||
assert len(extra.merkleRootMNList) == 32
|
||||
assert extra.merkleRootMNList == bfh(
|
||||
'2d126055d9cd81da35972dd5f11d8b7d24d23beeb9331d64d93ca74966fff912')
|
||||
assert len(extra.merkleRootQuorums) == 32
|
||||
assert extra.merkleRootQuorums == bfh(
|
||||
'0000000000000000000000000000000000000000000000000000000000000000')
|
||||
ser = tx.serialize()
|
||||
assert ser == test
|
||||
|
||||
|
||||
def test_axe_tx_pro_reg_tx():
|
||||
test = bfh(PRO_REG_TX)
|
||||
deser = lib_tx_axe.DeserializerAxe(test)
|
||||
tx = deser.read_tx()
|
||||
assert tx.version == 3
|
||||
assert tx.tx_type == 1
|
||||
extra = tx.extra_payload
|
||||
assert extra.version == 1
|
||||
assert extra.type == 0
|
||||
assert extra.mode == 0
|
||||
assert len(extra.collateralOutpoint.hash) == 32
|
||||
assert extra.collateralOutpoint.hash == bfh(
|
||||
'2181625260614470c020764d56d7a2eb9bedb0a2f65f0168c99a4fdf84657391')
|
||||
assert extra.collateralOutpoint.index == 0
|
||||
assert len(extra.ipAddress) == 16
|
||||
assert extra.ipAddress == bfh('00000000000000000000ffff74cb7f7f')
|
||||
assert extra.port == 9937
|
||||
assert len(extra.KeyIdOwner) == 20
|
||||
assert extra.KeyIdOwner == bfh(
|
||||
'c1a9c6453135e83be71635ac840652bbefc60786')
|
||||
assert len(extra.PubKeyOperator) == 48
|
||||
assert extra.PubKeyOperator == bfh(
|
||||
'1908c153792530dfe635bdf819ceb7963b624233a3465be94a4651ca36f7c0917d301c1e61485b68debc2f9fe5b7e84b')
|
||||
assert len(extra.KeyIdVoting) == 20
|
||||
assert extra.KeyIdVoting == bfh(
|
||||
'c1a9c6453135e83be71635ac840652bbefc60786')
|
||||
assert extra.operatorReward == 0
|
||||
assert extra.scriptPayout == bfh(
|
||||
'76a914950c9dea79cee4c4fea859c95fd534bba21f9a3088ac')
|
||||
assert len(extra.inputsHash) == 32
|
||||
assert extra.inputsHash == bfh(
|
||||
'f3a95bbe35ccdbe9d8cd3a875e3f80af725422bcf44d35ce79078df357c29bf9')
|
||||
assert extra.payloadSig == bfh(
|
||||
'2088b70bd05dbbd5a86d51abc78e33658f95ac01b98bc16dd537bcac5c48d3db437ee6c9b1d664e2a192b64b1893b3ce22b4ac47da9c4a0d148440be74527a43d4')
|
||||
ser = tx.serialize()
|
||||
assert ser == test
|
||||
|
||||
|
||||
def test_axe_tx_pro_up_serv_tx():
|
||||
test = bfh(PRO_UP_SERV_TX)
|
||||
deser = lib_tx_axe.DeserializerAxe(test)
|
||||
tx = deser.read_tx()
|
||||
assert tx.version == 3
|
||||
assert tx.tx_type == 2
|
||||
extra = tx.extra_payload
|
||||
assert extra.version == 1
|
||||
assert len(extra.proTxHash) == 32
|
||||
assert extra.proTxHash == bfh(
|
||||
'bef73450cab0889367710dd4ccd80cdb47557ad135dcb0e54f2cd8b9623cd573')
|
||||
assert len(extra.ipAddress) == 16
|
||||
assert extra.ipAddress == bfh('00000000000000000000ffff2d3f1f37')
|
||||
assert extra.port == 9999
|
||||
assert extra.scriptOperatorPayout == bfh( '')
|
||||
#not present in the test transaction
|
||||
assert len(extra.inputsHash) == 32
|
||||
assert extra.inputsHash == bfh(
|
||||
'768450381dca4e9888aa7be9a7725e0824696fc24f5a35de62916dc81b3085b3')
|
||||
assert len(extra.payloadSig) == 96
|
||||
assert extra.payloadSig == bfh( '077e02247c17992ba5ee9a2894e03c2e489b07cb9b751207dd51ca5c3dc6b67bada8f82a41c3137dbb203ce185caaccf1565e62c626e5225ff741e01faf4b09d8d7300dfb5c3e6f352120047b2e7b0547e5ea1198b615bf4826eaba252f97007' )
|
||||
|
||||
ser = tx.serialize()
|
||||
assert ser == test
|
||||
|
||||
|
||||
def test_axe_tx_pro_up_reg_tx():
|
||||
test = bfh(PRO_UP_REG_TX)
|
||||
deser = lib_tx_axe.DeserializerAxe(test)
|
||||
tx = deser.read_tx()
|
||||
assert tx.version == 3
|
||||
assert tx.tx_type == 3
|
||||
extra = tx.extra_payload
|
||||
assert extra.version == 1
|
||||
assert len(extra.proTxHash) == 32
|
||||
assert extra.proTxHash == bfh(
|
||||
'454bce26dde61cce5a8190928ed2af0f95c5bc053c88170b1a653028b36a29a3')
|
||||
assert extra.mode == 0
|
||||
assert len(extra.PubKeyOperator) == 48
|
||||
assert extra.PubKeyOperator == bfh(
|
||||
'8aba2efc6ef0305e8aadb650a5e5e15f7ea583968b48ea47bcec4bfaab108aa98f2e4ed0bb66946f7b65dff9ee92820d' )
|
||||
assert len(extra.KeyIdVoting) == 20
|
||||
print(extra.KeyIdVoting)
|
||||
#assert extra.KeyIdVoting == bfh(
|
||||
# 'c99a89fcafd3a4729860b2f9cd2ba4a7d965e9')
|
||||
assert extra.scriptPayout == bfh(
|
||||
'76a9148e124bfba342a13dec4d7a932284179a7f9c9e6188ac')
|
||||
assert len(extra.inputsHash) == 32
|
||||
assert extra.inputsHash == bfh(
|
||||
'd2972fcc5557d534cc6a9ed494e6213673521dbccacf4d3637994a5aaad721d3')
|
||||
assert extra.payloadSig == bfh( '20697182d7c398d4add6c49f0ddc7e71ec0253f0ff0d198b23913f8231ff18140f0b880feed08c267b0e9c70d9136c028c6126f7ae014879442b93c3a538ee6ac6' )
|
||||
|
||||
ser = tx.serialize()
|
||||
assert ser == test
|
||||
|
||||
|
||||
def test_axe_tx_pro_up_rev_tx():
|
||||
test = bfh(PRO_UP_REV_TX)
|
||||
deser = lib_tx_axe.DeserializerAxe(test)
|
||||
tx = deser.read_tx()
|
||||
assert tx.version == 3
|
||||
assert tx.tx_type == 4
|
||||
extra = tx.extra_payload
|
||||
assert extra.version == 1
|
||||
assert len(extra.proTxHash) == 32
|
||||
assert extra.proTxHash == bfh(
|
||||
'd1061c3f0f32e332f100f153041797eebd2702a5f419d2d057023f7f7238c922')
|
||||
assert extra.reason == 3
|
||||
assert len(extra.inputsHash) == 32
|
||||
assert extra.inputsHash == bfh(
|
||||
'41a7d06f62ec60981969414d738489e4a0d8d4dcfb74e8a1ad2182f4e3de97d9')
|
||||
assert len(extra.payloadSig) == 96
|
||||
assert extra.payloadSig == bfh(
|
||||
'0e4222e82aa968d8d1c6fda6a553d6071897c8985fda438922d773b7aeabdbaa22cb699b248c0e15bfd7b52e230920ab04ac4881aaffe836bfbc53c6e95671ede9a8185fceece5b3ce1480a824a67fd004a15a2bb34fabb82688344d0b6d2669' )
|
||||
ser = tx.serialize()
|
||||
assert ser == test
|
||||
|
||||
''' No DIP0005 in Axe
|
||||
def test_axe_tx_sub_tx_register_tx():
|
||||
test = bfh(SUB_TX_REGISTER)
|
||||
deser = lib_tx_axe.DeserializerAxe(test)
|
||||
tx = deser.read_tx()
|
||||
assert tx.version == 3
|
||||
assert tx.tx_type == 8
|
||||
extra = tx.extra_payload
|
||||
assert extra.version == 1
|
||||
assert extra.userName == b'abc'
|
||||
assert len(extra.pubKey) == 48
|
||||
assert extra.pubKey == bfh(
|
||||
'8e7042ec88acefcfe3d578914bb48c6bd71b3459d384e42374e8abfeffff'
|
||||
'ff01570b0000000000001976a91490c5ce9d')
|
||||
assert len(extra.payloadSig) == 96
|
||||
assert extra.payloadSig == bfh(
|
||||
'8bc992a88ac00000000a40100b67ffbbd095de31ea38446754e8abfeffff'
|
||||
'ff01570b0000000000001976a91490c5ce9d8bc992a88ac00000000a4010'
|
||||
'0b67ffbbd095de31ea38446754e8abfeffffff01570b0000000000001976'
|
||||
'a91490c5ce9d')
|
||||
ser = tx.serialize()
|
||||
assert ser == test
|
||||
|
||||
def test_axe_tx_sub_tx_topup_tx():
|
||||
test = bfh(SUB_TX_TOPUP)
|
||||
deser = lib_tx_axe.DeserializerAxe(test)
|
||||
tx = deser.read_tx()
|
||||
assert tx.version == 3
|
||||
assert tx.tx_type == 9
|
||||
extra = tx.extra_payload
|
||||
assert extra.version == 1
|
||||
assert len(extra.regTxHash) == 32
|
||||
assert extra.regTxHash == bfh(
|
||||
'd384e42374e8abfeffffff01570b000000a40100b67ffbbd095de31ea3844675')
|
||||
ser = tx.serialize()
|
||||
assert ser == test
|
||||
|
||||
|
||||
def test_axe_tx_sub_tx_reset_key_tx():
|
||||
test = bfh(SUB_TX_RESET_KEY)
|
||||
deser = lib_tx_axe.DeserializerAxe(test)
|
||||
tx = deser.read_tx()
|
||||
assert tx.version == 3
|
||||
assert tx.tx_type == 10
|
||||
extra = tx.extra_payload
|
||||
assert extra.version == 1
|
||||
assert len(extra.regTxHash) == 32
|
||||
assert extra.regTxHash == bfh(
|
||||
'd384e42374e8abfeffffff01570b000000a40100b67ffbbd095de31ea3844675')
|
||||
assert len(extra.hashPrevSubTx) == 32
|
||||
assert extra.hashPrevSubTx == bfh(
|
||||
'af3e98e9601210293360bf2a2e810673412bc6e8e0e358f3fb7bdbe9a667b3d0')
|
||||
assert extra.creditFee == 1000
|
||||
assert len(extra.newPubKey) == 48
|
||||
assert extra.newPubKey == bfh(
|
||||
'601210293360bf2a2e810673412bc6e8e0e358f3fb7bdbe9a667b3d0103f7'
|
||||
'61caf3e98e9601210293360bf2a2e810673')
|
||||
assert len(extra.payloadSig) == 96
|
||||
assert extra.payloadSig == bfh(
|
||||
'412bc6e8e0e358f3fb7bdbe9a667b3d0103f761caf3e98e9601210293360b'
|
||||
'f2a2e810673412bc6e8e0e358f3fb7bdbe9a667b3d0103f761caf3e98e960'
|
||||
'1210293360bf2a2e810673412bc6e8e0e358f3fb7bdbe9a667b3d0103f761'
|
||||
'cabcdefab')
|
||||
ser = tx.serialize()
|
||||
assert ser == test
|
||||
|
||||
|
||||
def test_axe_tx_sub_tx_close_account_tx():
|
||||
test = bfh(SUB_TX_CLOSE_ACCOUNT)
|
||||
deser = lib_tx_axe.DeserializerAxe(test)
|
||||
tx = deser.read_tx()
|
||||
assert tx.version == 3
|
||||
assert tx.tx_type == 11
|
||||
extra = tx.extra_payload
|
||||
assert extra.version == 1
|
||||
assert len(extra.regTxHash) == 32
|
||||
assert extra.regTxHash == bfh(
|
||||
'd384e42374e8abfeffffff01570b000000a40100b67ffbbd095de31ea3844675')
|
||||
assert len(extra.hashPrevSubTx) == 32
|
||||
assert extra.hashPrevSubTx == bfh(
|
||||
'af3e98e9601210293360bf2a2e810673412bc6e8e0e358f3fb7bdbe9a12bc6e8')
|
||||
assert extra.creditFee == 1000
|
||||
assert len(extra.payloadSig) == 96
|
||||
assert extra.payloadSig == bfh(
|
||||
'a62bc6e8e0e358f3fb7bdbe9a667b3d0103f761caf3e98e9601210293360b'
|
||||
'f2a2e810673412bc6e8e0e358f3fb7bdbe9a667b3d0103f761caf3e98e960'
|
||||
'1210293360bf2a2e810673412bc6e8e0e358f3fb7bdbe9a667b3d0103f761'
|
||||
'cabcdefab')
|
||||
ser = tx.serialize()
|
||||
assert ser == test
|
||||
'''
|
||||
|
||||
def test_axe_tx_unknown_spec_tx():
|
||||
test = bfh(UNKNOWN_SPEC_TX)
|
||||
deser = lib_tx_axe.DeserializerAxe(test)
|
||||
tx = deser.read_tx()
|
||||
assert tx.version == 3
|
||||
assert tx.tx_type == 187
|
||||
extra = tx.extra_payload
|
||||
assert extra == bfh(
|
||||
'0100d384e42374e8abfeffffff01570b000000a40100b67ffbbd095de31e'
|
||||
'a3844675af3e98e9601210293360bf2a2e810673412bc6e8e0e358f3fb7b'
|
||||
'dbe9a12bc6e8e0e358f3fb7bdbe9a62bc6e8e0e358f3fb7bdbe9a667b3d0'
|
||||
'103f761caf3e98e9601210293360bf2a2e810673412bc6e8e0e358f3fb7b'
|
||||
'dbe9a667b3d0103f761caf3e98e9601210293360bf2a2e810673412bc6e8'
|
||||
'e0e358f3fb7bdbe9a667b3d0103f761cabcdefab')
|
||||
ser = tx.serialize()
|
||||
assert ser == test
|
||||
|
||||
|
||||
def test_axe_tx_wrong_spec_tx():
|
||||
test = bfh(WRONG_SPEC_TX)
|
||||
deser = lib_tx_axe.DeserializerAxe(test)
|
||||
tx = deser.read_tx()
|
||||
assert tx.version == 12255234
|
||||
assert tx.tx_type == 0
|
||||
extra = tx.extra_payload
|
||||
assert extra == b''
|
||||
ser = tx.serialize()
|
||||
assert ser == test
|
||||
|
||||
|
||||
def test_axe_tx_serialize_wrong_tx_type():
|
||||
test = bfh(CB_TX)
|
||||
deser = lib_tx_axe.DeserializerAxe(test)
|
||||
tx = deser.read_tx()
|
||||
assert tx.tx_type == 5
|
||||
tx.tx_type = 4
|
||||
assert tx.tx_type == 4
|
||||
with pytest.raises(ValueError) as excinfo:
|
||||
ser = tx.serialize()
|
||||
assert ('Axe tx_type does not conform'
|
||||
' with extra payload class' in str(excinfo.value))
|
||||
@@ -0,0 +1,502 @@
|
||||
import pytest
|
||||
|
||||
import electrumx.lib.tx_dash as lib_tx_dash
|
||||
|
||||
|
||||
bfh = bytes.fromhex
|
||||
|
||||
|
||||
V2_TX = (
|
||||
'020000000192809f0b234cb850d71d020e678e93f074648ed0df5affd0c46d3bcb177f'
|
||||
'9ccf020000008b483045022100c5403bcf86c3ae7b8fd4ca0d1e4df6729cc1af05ff95'
|
||||
'd9726b43a64b41dd5d9902207fab615f41871885aa3062fc7d8f8d9d3dcbc2e4867c5d'
|
||||
'96dd7a176b99e927924141040baa4271a82c5f1a09a5ea63d763697ca0545b6049c4dd'
|
||||
'8e8d099dd91f2da10eb11e829000a82047ac56969fb582433067a21c3171e569d1832c'
|
||||
'34fdd793cfc8ffffffff030000000000000000226a20195ce612d20e5284eb78bb28c9'
|
||||
'c50d6139b10b77b2d5b2f94711b13162700472bfc53000000000001976a9144a519c63'
|
||||
'f985ba5ab8b71bb42f1ecb82a0a0d80788acf6984315000000001976a9148b80536aa3'
|
||||
'c460258cda834b86a46787c9a2b0bf88ac00000000')
|
||||
|
||||
|
||||
CB_TX = (
|
||||
'0300050001000000000000000000000000000000000000000000000000000000000000'
|
||||
'0000ffffffff1303c407040e2f5032506f6f6c2d74444153482fffffffff0448d6a73d'
|
||||
'000000001976a914293859173a34194d445c2962b97383e2a93d7cb288ac22fc433e00'
|
||||
'0000001976a914bf09c602c6b8f1db246aba5c37ad1cfdcb16b15e88ace9259c000000'
|
||||
'00004341047559d13c3f81b1fadbd8dd03e4b5a1c73b05e2b980e00d467aa9440b29c7'
|
||||
'de23664dde6428d75cafed22ae4f0d302e26c5c5a5dd4d3e1b796d7281bdc9430f35ac'
|
||||
'00000000000000002a6a28be61411c3c79b7fd45923118ba74d340afb248ae2edafe78'
|
||||
'c15e2d1aa337c942000000000000000000000000260100c407040076629a6e42fb5191'
|
||||
'88f65889fd3ac0201be87aa227462b5643e8bb2ec1d7a82a')
|
||||
|
||||
CB_TX_V2 = (
|
||||
'0300050001000000000000000000000000000000000000000000000000000000000000'
|
||||
'0000ffffffff1303c407040e2f5032506f6f6c2d74444153482fffffffff0448d6a73d'
|
||||
'000000001976a914293859173a34194d445c2962b97383e2a93d7cb288ac22fc433e00'
|
||||
'0000001976a914bf09c602c6b8f1db246aba5c37ad1cfdcb16b15e88ace9259c000000'
|
||||
'00004341047559d13c3f81b1fadbd8dd03e4b5a1c73b05e2b980e00d467aa9440b29c7'
|
||||
'de23664dde6428d75cafed22ae4f0d302e26c5c5a5dd4d3e1b796d7281bdc9430f35ac'
|
||||
'00000000000000002a6a28be61411c3c79b7fd45923118ba74d340afb248ae2edafe78'
|
||||
'c15e2d1aa337c942000000000000000000000000460200c407040076629a6e42fb5191'
|
||||
'88f65889fd3ac0201be87aa227462b5643e8bb2ec1d7a82a76629a6e42fb519188f658'
|
||||
'89fd3ac0201be87aa227462b5643e8bb2ec1d7a82a')
|
||||
|
||||
CB_TX_V3 = (
|
||||
'0300050001000000000000000000000000000000000000000000000000000000000000'
|
||||
'0000ffffffff06035cbe0d0101ffffffff0397f4e127000000001976a914c69a0bda7d'
|
||||
'aaae481be8def95e5f347a1d00a4b488ac94196f1600000000016a4dd5632500000000'
|
||||
'1976a914c69a0bda7daaae481be8def95e5f347a1d00a4b488ac00000000af03005cbe'
|
||||
'0d003c7a25cd3258d4141c1aca784232f28b92f94221c1d6add1c7221ebecffd201297'
|
||||
'52cf4e10c95caefd2972782eb6ab4bc64170c148c9f32191be3f09d546a5e500b097da'
|
||||
'dbd9741dabd85bec96ed8421499ec37aeb0ec48ff25c2a994a47e030ef1c5758bf1918'
|
||||
'e4fd04c9f7b149df160800a9fdbf08311b93484e545a876e81e3408a4c8358f11ce2c9'
|
||||
'c01206c39122875f9dbfea67e8953da4e63a1cd8551dfc94196f1600000000')
|
||||
|
||||
|
||||
PRO_REG_TX = (
|
||||
'030001000335f1c2ca44a1eb72e59f589df2852caacba39b7c0a5e61967f6b71d7a763'
|
||||
'3153000000006b483045022100b2d457bbe855abc365a7db9c8014ea106fdb6dae6327'
|
||||
'927fe81dfbdecf032b260220262e7e6c28899cd741db55c2e2ec35ed849cf99e78e36a'
|
||||
'70c2ec3dac3c2ef60a012102500859b69a4cad6cfe4cf6b606be25b367c562b3be9a24'
|
||||
'b06d60c7047ee18fa2feffffff473ac70b52b2260aa0e4bec818c5a8c71d37a1b17430'
|
||||
'75823c8e572ad71938b0000000006b483045022100fa4d57cdeb61f8ff1298fdc40256'
|
||||
'c68dfce320d44f584494c0a53233ddbe30a702206a50aaa245a6097d06c790fb1d7a37'
|
||||
'ced1622299c0aa93ebc018f1590d0eb15c012103f273126b24f755ab7e41311d03d545'
|
||||
'590c162ea179421c5e18271c57de1a1635feffffff4de1afa0a321bc88c34978d4eeba'
|
||||
'739256b86f8d8cdf47651b6f60e451f0a3de000000006a47304402202c4c5c48ac1d37'
|
||||
'9f6da8143664072d6545d64691ce4738e026adf80c9afab24f022053804b4166a342da'
|
||||
'38c538757680bebdc7785ce8c18a817fb3014fdaeec6d3bb0121028e99f6bc86489a43'
|
||||
'f953b2f0b046666efd7f7ad44da30f62ed5d32921556f8c5feffffff01c7430f000000'
|
||||
'00001976a914c1de5f0587dc39112a28644904b0f3ed3298a6ed88ac00000000fd1201'
|
||||
'0100000000004de1afa0a321bc88c34978d4eeba739256b86f8d8cdf47651b6f60e451'
|
||||
'f0a3de0100000000000000000000000000ffff12ca34aa752f2b3edeed6842db1f59cf'
|
||||
'35de1ab5721094f049d000ab986c589053b3f3bd720724e75e18581afdca54bce80d14'
|
||||
'750b1bcf9202158fe6c596ce8391815265747bd4a2009e2b3edeed6842db1f59cf35de'
|
||||
'1ab5721094f049d000001976a9149bf5948b901a1e3e54e42c6e10496a17cd4067e088'
|
||||
'ac54d046585434668b4ee664c597864248b8a6aac33a7b2f4fcd1cc1b5da474a8a411f'
|
||||
'c1617ae83406c92a9132f14f9fff1487f2890f401e776fdddd639bc5055c456268cf74'
|
||||
'97400d3196109c8cd31b94732caf6937d63de81d9a5be4db5beb83f9aa')
|
||||
|
||||
|
||||
PRO_REG_TX_V2 = (
|
||||
'03000100013d7f654493ff3c9e7ea26c326f435e72cf1ba88d687dd7532d686760221e'
|
||||
'0b27010000006a473044022076fbc6187b0e966faa4ebc6b06414317e1c1af11ca0a57'
|
||||
'4dace4b03abec1bec00220466d7d2d1adf396b8df5a8cc6afd064bd984e3676bd93f55'
|
||||
'4d1c7bfeeb67591f0121026d1a91dea1a6d6fcd9d998212c0914a903197bc3f39d4065'
|
||||
'c01857b6d379a8dcfeffffff010adff505000000001976a914beedf8a3a2f385046e11'
|
||||
'ac4606f42bec505d4e6888ac00000000fd2a010200010000003d7f654493ff3c9e7ea2'
|
||||
'6c326f435e72cf1ba88d687dd7532d686760221e0b2702000000000000000000000000'
|
||||
'00ffff7f0000012afd6cfacb0f86aa7f86200512b346504952b2ecdca2b3c39049cc46'
|
||||
'a565e8f2e91c9ec68b58379b99c506f6701e7bd5c8864d8954480abaa2c4ea53af9f31'
|
||||
'd60155e3df936a69e6f2b2014e943402adfdc16d8785971bd4ef4bf4011976a914d4bd'
|
||||
'717bc0ff02c9aa34cd72fcd73989f68d941288acdcc55e86aaad9f59533a5cca568bad'
|
||||
'bc04aa68e81ac61d5e2fa5ac732714c4b70319c63d1bf01d6893b01d1bef62f08f79d9'
|
||||
'6816622b632b411f8f268e41905bab8ad36115f1fdff74ce05bc53688a529fd93b797f'
|
||||
'4850c8250d73315814b8973b35d8633326269564b2ffb1469c806c8110ac9e0810aa52'
|
||||
'2f14')
|
||||
|
||||
|
||||
PRO_UP_SERV_TX = (
|
||||
'03000200010931c6b0ad7ce07f3c8aefeeb78e246a4fe6872bbf08ab6e4eb6a7b69acd'
|
||||
'64a6010000006b483045022100a2feb698c43c752738fabea281b7e9e5a3aa648a4c54'
|
||||
'1171e06d7c372db92c65022061c1ec3c92f2e76bb7fb1b548d854f19a41e6421267231'
|
||||
'74150412caf3e98e9601210293360bf2a2e810673412bc6e8e0e358f3fb7bdbe9a667b'
|
||||
'3d0103f761cc69a211feffffff0189fa433e000000001976a914551ab8ca96a9142217'
|
||||
'4d22769c3a4f90b2dcd0de88ac00000000ce01003c6dca244f49f19d3f09889753ffff'
|
||||
'1fec5bb8f9f5bd5bc09dabd999da21198f00000000000000000000ffff5fb735802711'
|
||||
'1976a91421851058431a7d722e8e8dd9509e7f2b8e7042ec88acefcfe3d578914bb48c'
|
||||
'6bd71b3459d384e4237446d521c9e2c6b6fcf019b5aafc99443fe14f644cfa47086e88'
|
||||
'97cf7b546a67723d4a8ec5353a82f962a96ec3cea328343b647aace2897d6eddd0b8c8'
|
||||
'ee0f2e56f6733aed2e9f0006caafa6fc21c18a013c619d6e37af8d2f0985e3b769abc3'
|
||||
'8ffa60e46c365a38d9fa0d44fd62')
|
||||
|
||||
|
||||
PRO_UP_SERV_TX_V2 = (
|
||||
'0300020001e3afeff168a2977a303f87d9a42ec7fc6f1e8fa814b11ea1088eadaea500'
|
||||
'51fd010000006a4730440220349326adf8f022189798cbe4eddfcff06405c3fe9fe28d'
|
||||
'701e0e1ef6cba8d100022018e64ce0bf5cca3b61a69909f54159ef3e87ca3b5103e587'
|
||||
'289f1f6150e1c3ed01210321a9da59a58b786f41ad7e012f52d229f125afcc25636e62'
|
||||
'00cc7d848129fe56feffffff014edff505000000001976a914633bb62fc65f43091ae6'
|
||||
'c319b7e4a85f10586b4588ac00000000e802000100d299fbe08bae8863e482ed70c4c0'
|
||||
'78ff0cbf05204f934ecf0fc114c6bdbd03d200000000000000000000ffff7f0000012a'
|
||||
'fd1976a914b7f5148c7f8b29370255b655be5ae9c7404b18c188ac4d3c4a39662eff4c'
|
||||
'b7bb00531b9048a81a9500cee046693a893ac928a46fb210af1bf741032fdf87ac1153'
|
||||
'dea88c0039a390fdf21f622062a4b4d6df357b3331924cb20e290979d3586b7a2c26b7'
|
||||
'95f9bd347374bb9d1cdb392ef265fa9255d7b2b5cb66251ce2ed01ce6a80ddb1d63a10'
|
||||
'982212a3b3ff35e6b682bbb32c889e88369a489447177867b8a1de78efa75cf9cf93ea'
|
||||
'd3113650')
|
||||
|
||||
|
||||
PRO_UP_REG_TX = (
|
||||
'0300030001f8f9a27ca1c727fb971d45983c9a08a0bbd76753f8eb7913130c72d94218'
|
||||
'8d32000000006a47304402205d530dc4e9e34b44fdf58f06fff0c225d80490be2861ad'
|
||||
'7fe5fed7e62b48053b022052a78b5beaccc468b7fdb80e47090cb54c351aa9aa82fa7e'
|
||||
'9b15b82d53b5f15a0121028106cde1660d2bfcc11231dfb1a05b60ded262d59e5e021a'
|
||||
'a3a814234013f4e9feffffff01c60c0000000000001976a91452a23d803da188cca952'
|
||||
'f9b7bc94c47c6fd1468a88ac00000000e40100aeb817f94b8e699b58130a53d2fbe98d'
|
||||
'5519c2abe3b15e6f36c9abeb32e4dcce00001061eb559a64427ad239830742ef59591c'
|
||||
'dbbdffda7d3f5e7a2d95b9607ad80e389191e44c59ea5987b85e6d0e3eb527b9e198fa'
|
||||
'7a745913c9278ec993d4472a95dac4251976a914eebbacffff3a55437803e0efb68a7d'
|
||||
'591e0409d188ac0eb0067e6ccdd2acb96e7279113702218f3f0ab6f2287e14c11c5be6'
|
||||
'f2051d5a4120cb00124d838b02207097048cb668244cd79df825eb2d4d211fd2c4604c'
|
||||
'18b30e1ae9bb654787144d16856676efff180889f05b5c9121a483b4ae3f0ea0ff3faf')
|
||||
|
||||
|
||||
PRO_UP_REV_TX = (
|
||||
'030004000100366cd80169116da28e387413e8e3660a7aedd65002b320d0bd165eea8e'
|
||||
'ba52000000006a4730440220043a639f4554842f38253c75d066e70098ef02b141d5ff'
|
||||
'dea9fc408d307fce1202205d5d779f416fbc431847d19d83ae90c4036cf9925d3c4852'
|
||||
'cdd5df25d5843a48012102688d37c6d08a236d7952cdbc310dcb344ddae8b02e028720'
|
||||
'1e79fd774509e8abfeffffff01570b0000000000001976a91490c5ce9d8bfefe3526d8'
|
||||
'538cd0ed5e5d472c992a88ac00000000a40100b67ffbbd095de31ea38446754b6bf251'
|
||||
'287936d2881d58b7c4efae0b54c75e9f0000eb073521b60306717f1d4feb3e9022f886'
|
||||
'b97bf981137684716a7d3d7e45b7fe83f4bb5530f7c5954e8b1ad50a74a9e1d65dcdcb'
|
||||
'e4acb8cbe3671abc7911e8c3954856c4da7e5fd242f2e4f5546f08d90849245bc593d1'
|
||||
'605654e1a99cd0a79e9729799742c48d4920044666ad25a85fd093559c43e4900e634c'
|
||||
'371b9b8d89ba')
|
||||
|
||||
|
||||
UNKNOWN_SPEC_TX = (
|
||||
'0300bb00010931c6b0ad7ce07f3c8aefeeb78e246a4fe6872bbf08ab6e4eb6a7b69acd'
|
||||
'64a6010000006b483045022100a2feb698c43c752738fabea281b7e9e5a3aa648a4c54'
|
||||
'1171e06d7c372db92c65022061c1ec3c92f2e76bb7fb1b548d854f19a41e6421267231'
|
||||
'74150412caf3e98e9601210293360bf2a2e810673412bc6e8e0e358f3fb7bdbe9a667b'
|
||||
'3d0103f761cc69a211feffffff0189fa433e000000001976a914551ab8ca96a9142217'
|
||||
'4d22769c3a4f90b2dcd0de88ac00000000aa0100d384e42374e8abfeffffff01570b00'
|
||||
'0000a40100b67ffbbd095de31ea3844675af3e98e9601210293360bf2a2e810673412b'
|
||||
'c6e8e0e358f3fb7bdbe9a12bc6e8e0e358f3fb7bdbe9a62bc6e8e0e358f3fb7bdbe9a6'
|
||||
'67b3d0103f761caf3e98e9601210293360bf2a2e810673412bc6e8e0e358f3fb7bdbe9'
|
||||
'a667b3d0103f761caf3e98e9601210293360bf2a2e810673412bc6e8e0e358f3fb7bdb'
|
||||
'e9a667b3d0103f761cabcdefab')
|
||||
|
||||
|
||||
WRONG_SPEC_TX = ( # Tx version < 3
|
||||
'0200bb00010931c6b0ad7ce07f3c8aefeeb78e246a4fe6872bbf08ab6e4eb6a7b69acd'
|
||||
'64a6010000006b483045022100a2feb698c43c752738fabea281b7e9e5a3aa648a4c54'
|
||||
'1171e06d7c372db92c65022061c1ec3c92f2e76bb7fb1b548d854f19a41e6421267231'
|
||||
'74150412caf3e98e9601210293360bf2a2e810673412bc6e8e0e358f3fb7bdbe9a667b'
|
||||
'3d0103f761cc69a211feffffff0189fa433e000000001976a914551ab8ca96a9142217'
|
||||
'4d22769c3a4f90b2dcd0de88ac00000000')
|
||||
|
||||
|
||||
def test_dash_v2_tx():
|
||||
test = bfh(V2_TX)
|
||||
deser = lib_tx_dash.DeserializerDash(test)
|
||||
tx = deser.read_tx()
|
||||
assert tx.version == 2
|
||||
assert tx.tx_type == 0
|
||||
assert tx.extra_payload == b''
|
||||
ser = tx.serialize()
|
||||
assert ser == test
|
||||
|
||||
|
||||
def test_dash_tx_cb_tx():
|
||||
test = bfh(CB_TX)
|
||||
deser = lib_tx_dash.DeserializerDash(test)
|
||||
tx = deser.read_tx()
|
||||
assert tx.version == 3
|
||||
assert tx.tx_type == 5
|
||||
extra = tx.extra_payload
|
||||
assert extra.version == 1
|
||||
assert extra.height == 264132
|
||||
assert len(extra.merkleRootMNList) == 32
|
||||
assert extra.merkleRootMNList == bfh(
|
||||
'76629a6e42fb519188f65889fd3ac0201be87aa227462b5643e8bb2ec1d7a82a')
|
||||
ser = tx.serialize()
|
||||
assert ser == test
|
||||
|
||||
|
||||
def test_dash_tx_cb_tx_v2():
|
||||
test = bfh(CB_TX_V2)
|
||||
deser = lib_tx_dash.DeserializerDash(test)
|
||||
tx = deser.read_tx()
|
||||
assert tx.version == 3
|
||||
assert tx.tx_type == 5
|
||||
extra = tx.extra_payload
|
||||
assert extra.version == 2
|
||||
assert extra.height == 264132
|
||||
assert len(extra.merkleRootMNList) == 32
|
||||
assert extra.merkleRootMNList == bfh(
|
||||
'76629a6e42fb519188f65889fd3ac0201be87aa227462b5643e8bb2ec1d7a82a')
|
||||
assert len(extra.merkleRootQuorums) == 32
|
||||
assert extra.merkleRootQuorums == bfh(
|
||||
'76629a6e42fb519188f65889fd3ac0201be87aa227462b5643e8bb2ec1d7a82a')
|
||||
ser = tx.serialize()
|
||||
assert ser == test
|
||||
|
||||
|
||||
def test_dash_tx_cb_tx_v3():
|
||||
test = bfh(CB_TX_V3)
|
||||
deser = lib_tx_dash.DeserializerDash(test)
|
||||
tx = deser.read_tx()
|
||||
assert tx.version == 3
|
||||
assert tx.tx_type == 5
|
||||
extra = tx.extra_payload
|
||||
assert extra.version == 3
|
||||
assert extra.height == 900700
|
||||
assert len(extra.merkleRootMNList) == 32
|
||||
assert extra.merkleRootMNList == bfh(
|
||||
'3c7a25cd3258d4141c1aca784232f28b92f94221c1d6add1c7221ebecffd2012')
|
||||
assert len(extra.merkleRootQuorums) == 32
|
||||
assert extra.merkleRootQuorums == bfh(
|
||||
'9752cf4e10c95caefd2972782eb6ab4bc64170c148c9f32191be3f09d546a5e5')
|
||||
assert extra.bestCLHeightDiff == 0
|
||||
assert len(extra.bestCLSignature) == 96
|
||||
assert extra.bestCLSignature == bfh(
|
||||
'b097dadbd9741dabd85bec96ed8421499ec37aeb0ec48ff25c2a994a47e030ef'
|
||||
'1c5758bf1918e4fd04c9f7b149df160800a9fdbf08311b93484e545a876e81e3'
|
||||
'408a4c8358f11ce2c9c01206c39122875f9dbfea67e8953da4e63a1cd8551dfc')
|
||||
assert extra.assetLockedAmount == 376379796
|
||||
ser = tx.serialize()
|
||||
assert ser == test
|
||||
|
||||
|
||||
def test_dash_tx_pro_reg_tx():
|
||||
test = bfh(PRO_REG_TX)
|
||||
deser = lib_tx_dash.DeserializerDash(test)
|
||||
tx = deser.read_tx()
|
||||
assert tx.version == 3
|
||||
assert tx.tx_type == 1
|
||||
extra = tx.extra_payload
|
||||
assert extra.version == 1
|
||||
assert extra.type == 0
|
||||
assert extra.mode == 0
|
||||
assert len(extra.collateralOutpoint.hash) == 32
|
||||
assert extra.collateralOutpoint.hash == bfh(
|
||||
'4de1afa0a321bc88c34978d4eeba739256b86f8d8cdf47651b6f60e451f0a3de')
|
||||
assert extra.collateralOutpoint.index == 1
|
||||
assert len(extra.ipAddress) == 16
|
||||
assert extra.ipAddress == bfh('00000000000000000000ffff12ca34aa')
|
||||
assert extra.port == 29999
|
||||
assert len(extra.KeyIdOwner) == 20
|
||||
assert extra.KeyIdOwner == bfh(
|
||||
'2b3edeed6842db1f59cf35de1ab5721094f049d0')
|
||||
assert len(extra.PubKeyOperator) == 48
|
||||
assert extra.PubKeyOperator == bfh(
|
||||
'00ab986c589053b3f3bd720724e75e18581afdca54bce80d14750b1bcf920215'
|
||||
'8fe6c596ce8391815265747bd4a2009e')
|
||||
assert len(extra.KeyIdVoting) == 20
|
||||
assert extra.KeyIdVoting == bfh(
|
||||
'2b3edeed6842db1f59cf35de1ab5721094f049d0')
|
||||
assert extra.operatorReward == 0
|
||||
assert extra.scriptPayout == bfh(
|
||||
'76a9149bf5948b901a1e3e54e42c6e10496a17cd4067e088ac')
|
||||
assert len(extra.inputsHash) == 32
|
||||
assert extra.inputsHash == bfh(
|
||||
'54d046585434668b4ee664c597864248b8a6aac33a7b2f4fcd1cc1b5da474a8a')
|
||||
assert extra.payloadSig == bfh(
|
||||
'1fc1617ae83406c92a9132f14f9fff1487f2890f401e776fdddd639bc505'
|
||||
'5c456268cf7497400d3196109c8cd31b94732caf6937d63de81d9a5be4db'
|
||||
'5beb83f9aa')
|
||||
ser = tx.serialize()
|
||||
assert ser == test
|
||||
|
||||
def test_dash_tx_pro_reg_tx_v2():
|
||||
test = bfh(PRO_REG_TX_V2)
|
||||
deser = lib_tx_dash.DeserializerDash(test)
|
||||
tx = deser.read_tx()
|
||||
assert tx.version == 3
|
||||
assert tx.tx_type == 1
|
||||
extra = tx.extra_payload
|
||||
assert extra.version == 2
|
||||
assert extra.type == 1
|
||||
assert extra.mode == 0
|
||||
assert len(extra.collateralOutpoint.hash) == 32
|
||||
assert extra.collateralOutpoint.hash == bfh(
|
||||
'3d7f654493ff3c9e7ea26c326f435e72cf1ba88d687dd7532d686760221e0b27')
|
||||
assert extra.collateralOutpoint.index == 2
|
||||
assert len(extra.ipAddress) == 16
|
||||
assert extra.ipAddress == bfh('00000000000000000000ffff7f000001')
|
||||
assert extra.port == 11005
|
||||
assert len(extra.KeyIdOwner) == 20
|
||||
assert extra.KeyIdOwner == bfh(
|
||||
'6cfacb0f86aa7f86200512b346504952b2ecdca2')
|
||||
assert len(extra.PubKeyOperator) == 48
|
||||
assert extra.PubKeyOperator == bfh(
|
||||
'b3c39049cc46a565e8f2e91c9ec68b58379b99c506f6701e7bd5c8864d895448'
|
||||
'0abaa2c4ea53af9f31d60155e3df936a')
|
||||
assert len(extra.KeyIdVoting) == 20
|
||||
assert extra.KeyIdVoting == bfh(
|
||||
'69e6f2b2014e943402adfdc16d8785971bd4ef4b')
|
||||
assert extra.operatorReward == 500
|
||||
assert extra.scriptPayout == bfh(
|
||||
'76a914d4bd717bc0ff02c9aa34cd72fcd73989f68d941288ac')
|
||||
assert len(extra.inputsHash) == 32
|
||||
assert extra.inputsHash == bfh(
|
||||
'dcc55e86aaad9f59533a5cca568badbc04aa68e81ac61d5e2fa5ac732714c4b7')
|
||||
assert len(extra.platformNodeID) == 20
|
||||
assert extra.platformNodeID == bfh(
|
||||
'0319c63d1bf01d6893b01d1bef62f08f79d96816')
|
||||
assert extra.platformP2PPort == 11106
|
||||
assert extra.platformHTTPPort == 11107
|
||||
assert extra.payloadSig == bfh(
|
||||
'1f8f268e41905bab8ad36115f1fdff74ce05bc53688a529fd93b797f4850'
|
||||
'c8250d73315814b8973b35d8633326269564b2ffb1469c806c8110ac9e08'
|
||||
'10aa522f14')
|
||||
ser = tx.serialize()
|
||||
assert ser == test
|
||||
|
||||
|
||||
def test_dash_tx_pro_up_serv_tx():
|
||||
test = bfh(PRO_UP_SERV_TX)
|
||||
deser = lib_tx_dash.DeserializerDash(test)
|
||||
tx = deser.read_tx()
|
||||
assert tx.version == 3
|
||||
assert tx.tx_type == 2
|
||||
extra = tx.extra_payload
|
||||
assert extra.version == 1
|
||||
assert len(extra.proTxHash) == 32
|
||||
assert extra.proTxHash == bfh(
|
||||
'3c6dca244f49f19d3f09889753ffff1fec5bb8f9f5bd5bc09dabd999da21198f')
|
||||
assert len(extra.ipAddress) == 16
|
||||
assert extra.ipAddress == bfh('00000000000000000000ffff5fb73580')
|
||||
assert extra.port == 10001
|
||||
assert extra.scriptOperatorPayout == bfh(
|
||||
'76a91421851058431a7d722e8e8dd9509e7f2b8e7042ec88ac')
|
||||
assert len(extra.inputsHash) == 32
|
||||
assert extra.inputsHash == bfh(
|
||||
'efcfe3d578914bb48c6bd71b3459d384e4237446d521c9e2c6'
|
||||
'b6fcf019b5aafc')
|
||||
assert len(extra.payloadSig) == 96
|
||||
assert extra.payloadSig == bfh(
|
||||
'99443fe14f644cfa47086e8897cf7b546a67723d4a8ec5353a82f962a96e'
|
||||
'c3cea328343b647aace2897d6eddd0b8c8ee0f2e56f6733aed2e9f0006ca'
|
||||
'afa6fc21c18a013c619d6e37af8d2f0985e3b769abc38ffa60e46c365a38'
|
||||
'd9fa0d44fd62')
|
||||
ser = tx.serialize()
|
||||
assert ser == test
|
||||
|
||||
|
||||
def test_dash_tx_pro_up_serv_tx_v2():
|
||||
test = bfh(PRO_UP_SERV_TX_V2)
|
||||
deser = lib_tx_dash.DeserializerDash(test)
|
||||
tx = deser.read_tx()
|
||||
assert tx.version == 3
|
||||
assert tx.tx_type == 2
|
||||
extra = tx.extra_payload
|
||||
assert extra.version == 2
|
||||
assert len(extra.proTxHash) == 32
|
||||
assert extra.proTxHash == bfh(
|
||||
'd299fbe08bae8863e482ed70c4c078ff0cbf05204f934ecf0fc114c6bdbd03d2')
|
||||
assert len(extra.ipAddress) == 16
|
||||
assert extra.ipAddress == bfh('00000000000000000000ffff7f000001')
|
||||
assert extra.port == 11005
|
||||
assert extra.scriptOperatorPayout == bfh(
|
||||
'76a914b7f5148c7f8b29370255b655be5ae9c7404b18c188ac')
|
||||
assert len(extra.inputsHash) == 32
|
||||
assert extra.inputsHash == bfh(
|
||||
'4d3c4a39662eff4cb7bb00531b9048a81a9500cee046693a89'
|
||||
'3ac928a46fb210')
|
||||
assert len(extra.platformNodeID) == 20
|
||||
assert extra.platformNodeID == bfh(
|
||||
'af1bf741032fdf87ac1153dea88c0039a390fdf2')
|
||||
assert extra.platformP2PPort == 25119
|
||||
assert extra.platformHTTPPort == 25120
|
||||
assert len(extra.payloadSig) == 96
|
||||
assert extra.payloadSig == bfh(
|
||||
'a4b4d6df357b3331924cb20e290979d3586b7a2c26b795f9bd347374bb9d'
|
||||
'1cdb392ef265fa9255d7b2b5cb66251ce2ed01ce6a80ddb1d63a10982212'
|
||||
'a3b3ff35e6b682bbb32c889e88369a489447177867b8a1de78efa75cf9cf'
|
||||
'93ead3113650')
|
||||
ser = tx.serialize()
|
||||
assert ser == test
|
||||
|
||||
|
||||
def test_dash_tx_pro_up_reg_tx():
|
||||
test = bfh(PRO_UP_REG_TX)
|
||||
deser = lib_tx_dash.DeserializerDash(test)
|
||||
tx = deser.read_tx()
|
||||
assert tx.version == 3
|
||||
assert tx.tx_type == 3
|
||||
extra = tx.extra_payload
|
||||
assert extra.version == 1
|
||||
assert len(extra.proTxHash) == 32
|
||||
assert extra.proTxHash == bfh(
|
||||
'aeb817f94b8e699b58130a53d2fbe98d5519c2abe3b15e6f36c9abeb32e4dcce')
|
||||
assert extra.mode == 0
|
||||
assert len(extra.PubKeyOperator) == 48
|
||||
assert extra.PubKeyOperator == bfh(
|
||||
'1061eb559a64427ad239830742ef59591cdbbdffda7d3f5e7a2d95b9607a'
|
||||
'd80e389191e44c59ea5987b85e6d0e3eb527')
|
||||
assert len(extra.KeyIdVoting) == 20
|
||||
assert extra.KeyIdVoting == bfh(
|
||||
'b9e198fa7a745913c9278ec993d4472a95dac425')
|
||||
assert extra.scriptPayout == bfh(
|
||||
'76a914eebbacffff3a55437803e0efb68a7d591e0409d188ac')
|
||||
assert len(extra.inputsHash) == 32
|
||||
assert extra.inputsHash == bfh(
|
||||
'0eb0067e6ccdd2acb96e7279113702218f3f0ab6f2287e14c11c5be6f2051d5a')
|
||||
assert extra.payloadSig == bfh(
|
||||
'20cb00124d838b02207097048cb668244cd79df825eb2d4d211fd2c4604c1'
|
||||
'8b30e1ae9bb654787144d16856676efff180889f05b5c9121a483b4ae3f0e'
|
||||
'a0ff3faf')
|
||||
ser = tx.serialize()
|
||||
assert ser == test
|
||||
|
||||
|
||||
def test_dash_tx_pro_up_rev_tx():
|
||||
test = bfh(PRO_UP_REV_TX)
|
||||
deser = lib_tx_dash.DeserializerDash(test)
|
||||
tx = deser.read_tx()
|
||||
assert tx.version == 3
|
||||
assert tx.tx_type == 4
|
||||
extra = tx.extra_payload
|
||||
assert extra.version == 1
|
||||
assert len(extra.proTxHash) == 32
|
||||
assert extra.proTxHash == bfh(
|
||||
'b67ffbbd095de31ea38446754b6bf251287936d2881d58b7c4efae0b54c75e9f')
|
||||
assert extra.reason == 0
|
||||
assert len(extra.inputsHash) == 32
|
||||
assert extra.inputsHash == bfh(
|
||||
'eb073521b60306717f1d4feb3e9022f886b97bf981137684716a7d3d7e45b7fe')
|
||||
assert len(extra.payloadSig) == 96
|
||||
assert extra.payloadSig == bfh(
|
||||
'83f4bb5530f7c5954e8b1ad50a74a9e1d65dcdcbe4acb8cbe3671abc7911'
|
||||
'e8c3954856c4da7e5fd242f2e4f5546f08d90849245bc593d1605654e1a9'
|
||||
'9cd0a79e9729799742c48d4920044666ad25a85fd093559c43e4900e634c'
|
||||
'371b9b8d89ba')
|
||||
ser = tx.serialize()
|
||||
assert ser == test
|
||||
|
||||
|
||||
def test_dash_tx_unknown_spec_tx():
|
||||
test = bfh(UNKNOWN_SPEC_TX)
|
||||
deser = lib_tx_dash.DeserializerDash(test)
|
||||
tx = deser.read_tx()
|
||||
assert tx.version == 3
|
||||
assert tx.tx_type == 187
|
||||
extra = tx.extra_payload
|
||||
assert extra == bfh(
|
||||
'0100d384e42374e8abfeffffff01570b000000a40100b67ffbbd095de31e'
|
||||
'a3844675af3e98e9601210293360bf2a2e810673412bc6e8e0e358f3fb7b'
|
||||
'dbe9a12bc6e8e0e358f3fb7bdbe9a62bc6e8e0e358f3fb7bdbe9a667b3d0'
|
||||
'103f761caf3e98e9601210293360bf2a2e810673412bc6e8e0e358f3fb7b'
|
||||
'dbe9a667b3d0103f761caf3e98e9601210293360bf2a2e810673412bc6e8'
|
||||
'e0e358f3fb7bdbe9a667b3d0103f761cabcdefab')
|
||||
ser = tx.serialize()
|
||||
assert ser == test
|
||||
|
||||
|
||||
def test_dash_tx_wrong_spec_tx():
|
||||
test = bfh(WRONG_SPEC_TX)
|
||||
deser = lib_tx_dash.DeserializerDash(test)
|
||||
tx = deser.read_tx()
|
||||
assert tx.version == 12255234
|
||||
assert tx.tx_type == 0
|
||||
extra = tx.extra_payload
|
||||
assert extra == b''
|
||||
ser = tx.serialize()
|
||||
assert ser == test
|
||||
|
||||
|
||||
def test_dash_tx_serialize_wrong_tx_type():
|
||||
test = bfh(CB_TX)
|
||||
deser = lib_tx_dash.DeserializerDash(test)
|
||||
tx = deser.read_tx()
|
||||
assert tx.tx_type == 5
|
||||
tx.tx_type = 4
|
||||
assert tx.tx_type == 4
|
||||
with pytest.raises(ValueError) as excinfo:
|
||||
ser = tx.serialize()
|
||||
assert ('Dash tx_type does not conform'
|
||||
' with extra payload class' in str(excinfo.value))
|
||||
@@ -0,0 +1,54 @@
|
||||
import electrumx.lib.tx as tx_lib
|
||||
|
||||
tests = [
|
||||
"0100000001000000000000000000000000000000000000000000000000000000000000"
|
||||
"000001000000fd2805c4267ec1112af809d3f18d118ae574af82a24a3311454d88aa15"
|
||||
"a2d4d51985a2d00000ee1a674c9a7abb62fce054d62c56fdf511eebb3c86301651f8d9"
|
||||
"f24b6dbc72c00000ac34e72f3af4ebb6ea84a1baf7b088f0d262934e8fa6abb974b1d3"
|
||||
"4e38dd88600100f251cbdac8a3ae679a014a5692267ed68acde7c238379788cdd9c2e4"
|
||||
"d06b1e09000015de8545abd016297392901e805bc303d9dff92e6414707c039a3bba26"
|
||||
"ac424f19aa67359d4970398d7ec9c0ec88cb7c8935176795103f07cb60e93e7d499406"
|
||||
"c8ba92b067b83bf7a42235337492f60bad0f4d3524619b436521213fd7859149ac1788"
|
||||
"6154bd82e5bcf76b1a2f54360758a834f17ebcd580548364db3ce3cdfd9ff688535b8f"
|
||||
"eb76a51744248e3fdead193a69912db593f5c7acd72a3fe17b8664dfd33a1884ae80b6"
|
||||
"18770a93c4e650dba3e0e7b082d28e162a9aa71301df35200366ae420db5d1ba79db51"
|
||||
"937aa44be1209ccb28c43ac26cf84cd9312d70f3a6a61b4ebfccebc3796090d755df74"
|
||||
"6838a923a7e408bdeca7fb961361aceceb2018f882edd38fe9fc083c03369afc218dbf"
|
||||
"9d48f64a5eaf1615b59cf71c7c79b8ac06f323782fcdef5b510e89b8cd02c9207c3cff"
|
||||
"6cc547767c67cd0dbecf479abb027de64ac57e8b368594791dbb6021edc5bc00b00d3a"
|
||||
"05789b3b2e3ab7c05170efe7d55c502327c37fad9875ca59d6249edc4d70a11c4df782"
|
||||
"c6b97bd79f80fe43c4b645a0b891b078318094d3c88db56a636502255fffa6eabb29e5"
|
||||
"18e2b33ddc49b963702f1787b6c4667630aed09a490688dc689a588471d398d3c90be9"
|
||||
"11076225935f6473737d7dfbe63b714d3a27cf07120e5c4f95d564b25830e7a7dd0261"
|
||||
"09743e2a9d078313fbe76e799fbc599e1052afc672a5573be8808254acd4a0f78fb5d9"
|
||||
"79e28bf1303ed28e88d84965925560c336202f8571d46b6a49e17a04697a15e2f195f9"
|
||||
"ec0680e5fef25b9f7003f66644da1a81257377c68a15de0f58b89927240e358388269e"
|
||||
"22855d1a605bb12d74dc954e27a31b8c5290e7ee3596a146254c4b0baaacc7c73a9f18"
|
||||
"6d580dbb951481bcba737566f7dc5ccb0ba5cfced401877db3aa7139e68411ef40cfd3"
|
||||
"a1b9a951998b20f3a3d8aef73d073ccfeeadeab56925055daed9ae93a5b1ab887f1ea1"
|
||||
"75076a9153b31fb7e581f7b0776c69583967fae7c0bd95e4d6c69a7649e6cddb3eae94"
|
||||
"1e843774aee8b5f707957cb7d12705746208431da75c5aa05be1321298b6311c22d193"
|
||||
"7afae2bdd65400008752b06f1ecc26dc59b579f9e8f20ee52d526627ecd7f4c579b2eb"
|
||||
"cf7c5aa5390000af608e02424ceeaf68cef06f6247011188724ec554e8e9163e9512c9"
|
||||
"e18978af0000117e5cf334ff7dd4858397b15235895bd76ceb9397a2d226272a5e84e5"
|
||||
"2d954d01006480c480ce0805f7377736eaebdb698f0fcd729726406691a09194de98c6"
|
||||
"09d601004d93ab877bdc866b6944dc654138b784b0dd81fd037811afff20fb85b69b61"
|
||||
"910100af16962e0f953579c123b31e211d53258d19147d5d7736656ffa23bf8a6c9b1c"
|
||||
"010018da2ac49971b595959c760e264ec6f2362d68093c5e6785da88f1204b24b02a99"
|
||||
"841a25d89984202a97c10ae2b7e9780970c6a7862991d5f97f7a21b839c6471e000000"
|
||||
"00e1f5050000000039c71b4fbdbf35e4aeabd312f560f07ff271b983d788bec185a86b"
|
||||
"03ffe691ee2103686b4bfb98e20953850634420bc147eeca3377fb726e1069a53e3fc8"
|
||||
"65744b3e40c0348010fa0c172c89eb3c87e9515516ccdc3939ef0c2a056faaf637fd9b"
|
||||
"af51001f5caaa1a654e3af936ac213fc9688b093d950865026534a2d5d09834a4408ff"
|
||||
"ffffff01605af405000000001976a914a201533465a5d9a18b958cc1eed30bc3b087e3"
|
||||
"5b88acb2e20000"
|
||||
]
|
||||
|
||||
def test_tx_serialiazation():
|
||||
for test in tests:
|
||||
test = bytes.fromhex(test)
|
||||
deser_xzc = tx_lib.DeserializerZcoin(test)
|
||||
tx = deser_xzc.read_tx()
|
||||
assert tx.inputs[0].prev_txid_rev == tx_lib.ZERO
|
||||
assert tx.inputs[0].prev_idx == tx_lib.MINUS_1
|
||||
|
||||
@@ -0,0 +1,216 @@
|
||||
import os
|
||||
|
||||
import pytest
|
||||
|
||||
from electrumx.lib import util, tx
|
||||
|
||||
|
||||
def test_formatted_time():
|
||||
assert util.formatted_time(0) == '00s'
|
||||
assert util.formatted_time(59) == '59s'
|
||||
assert util.formatted_time(60) == '01m 00s'
|
||||
assert util.formatted_time(3599) == '59m 59s'
|
||||
assert util.formatted_time(3600) == '01h 00m 00s'
|
||||
assert util.formatted_time(3600*24) == '1d 00h 00m'
|
||||
assert util.formatted_time(3600*24*367) == '367d 00h 00m'
|
||||
assert util.formatted_time(3600*24, ':') == '1d:00h:00m'
|
||||
|
||||
def test_deep_getsizeof():
|
||||
int_t = util.deep_getsizeof(1)
|
||||
assert util.deep_getsizeof('foo') == util.deep_getsizeof('') + 3
|
||||
assert util.deep_getsizeof([1, 1]) > 2 * int_t
|
||||
assert util.deep_getsizeof({1: 1}) > 2 * int_t
|
||||
assert util.deep_getsizeof({1: {1: 1}}) > 3 * int_t
|
||||
|
||||
|
||||
class Base:
|
||||
pass
|
||||
|
||||
|
||||
class A(Base):
|
||||
pass
|
||||
|
||||
|
||||
class B(Base):
|
||||
pass
|
||||
|
||||
|
||||
class C(A):
|
||||
pass
|
||||
|
||||
|
||||
def test_subclasses():
|
||||
assert util.subclasses(Base) == [A, B, C]
|
||||
assert util.subclasses(Base, strict=False) == [A, B, Base, C]
|
||||
|
||||
|
||||
def test_chunks():
|
||||
assert list(util.chunks([1, 2, 3, 4, 5], 2)) == [[1, 2], [3, 4], [5]]
|
||||
|
||||
|
||||
def test_increment_byte_string():
|
||||
assert util.increment_byte_string(b'1') == b'2'
|
||||
assert util.increment_byte_string(b'\x01\x01') == b'\x01\x02'
|
||||
assert util.increment_byte_string(b'\xff\xff') is None
|
||||
|
||||
|
||||
def test_bytes_to_int():
|
||||
assert util.bytes_to_int(b'\x07[\xcd\x15') == 123456789
|
||||
|
||||
|
||||
def test_int_to_bytes():
|
||||
assert util.int_to_bytes(456789) == b'\x06\xf8U'
|
||||
|
||||
|
||||
def test_LogicalFile(tmpdir):
|
||||
prefix = os.path.join(tmpdir, 'log')
|
||||
L = util.LogicalFile(prefix, 2, 6)
|
||||
with pytest.raises(FileNotFoundError):
|
||||
L.open_file(0, create=False)
|
||||
|
||||
# Check L.open creates a file
|
||||
with L.open_file(8, create=True) as f:
|
||||
pass
|
||||
with util.open_file(prefix + '01') as f:
|
||||
pass
|
||||
|
||||
L.write(0, b'987')
|
||||
assert L.read(0, -1) == b'987'
|
||||
assert L.read(0, 4) == b'987'
|
||||
assert L.read(1, 1) == b'8'
|
||||
|
||||
L.write(0, b'01234567890')
|
||||
assert L.read(0, -1) == b'01234567890'
|
||||
assert L.read(5, -1) == b'567890'
|
||||
with util.open_file(prefix + '01') as f:
|
||||
assert f.read(-1) == b'67890'
|
||||
|
||||
# Test file boundary
|
||||
L.write(0, b'957' * 6)
|
||||
assert L.read(0, -1) == b'957' * 6
|
||||
|
||||
def test_open_fns(tmpdir):
|
||||
tmpfile = os.path.join(tmpdir, 'file1')
|
||||
with pytest.raises(FileNotFoundError):
|
||||
util.open_file(tmpfile)
|
||||
with util.open_file(tmpfile, create=True) as f:
|
||||
f.write(b'56')
|
||||
with util.open_file(tmpfile) as f:
|
||||
assert f.read(3) == b'56'
|
||||
|
||||
# Test open_truncate truncates and creates
|
||||
with util.open_truncate(tmpfile) as f:
|
||||
assert f.read(3) == b''
|
||||
tmpfile = os.path.join(tmpdir, 'file2')
|
||||
with util.open_truncate(tmpfile) as f:
|
||||
assert f.read(3) == b''
|
||||
|
||||
def test_address_string():
|
||||
assert util.address_string(('foo.bar', 84)) == 'foo.bar:84'
|
||||
assert util.address_string(('1.2.3.4', 84)) == '1.2.3.4:84'
|
||||
assert util.address_string(('0a::23', 84)) == '[a::23]:84'
|
||||
|
||||
def test_protocol_tuple():
|
||||
assert util.protocol_tuple(None) == (0, )
|
||||
assert util.protocol_tuple("foo") == (0, )
|
||||
assert util.protocol_tuple(1) == (0, )
|
||||
assert util.protocol_tuple("1") == (1, )
|
||||
assert util.protocol_tuple("0.1") == (0, 1)
|
||||
assert util.protocol_tuple("0.10") == (0, 10)
|
||||
assert util.protocol_tuple("2.5.3") == (2, 5, 3)
|
||||
|
||||
def test_version_string():
|
||||
assert util.version_string(()) == "0.0"
|
||||
assert util.version_string((1, )) == "1.0"
|
||||
assert util.version_string((1, 2)) == "1.2"
|
||||
assert util.version_string((1, 3, 2)) == "1.3.2"
|
||||
|
||||
def test_protocol_version():
|
||||
assert util.protocol_version(None, (1, 0), (1, 0)) == ((1, 0), (1, 0))
|
||||
assert util.protocol_version("0.10", (0, 1), (1, 1)) == ((0, 10), (0, 10))
|
||||
|
||||
assert util.protocol_version("1.0", (1, 0), (1, 0)) == ((1, 0), (1, 0))
|
||||
assert util.protocol_version("1.0", (1, 0), (1, 1)) == ((1, 0), (1, 0))
|
||||
assert util.protocol_version("1.1", (1, 0), (1, 1)) == ((1, 1), (1, 1))
|
||||
assert util.protocol_version("1.2", (1, 0), (1, 1)) == (None, (1, 2))
|
||||
assert util.protocol_version("0.9", (1, 0), (1, 1)) == (None, (0, 9))
|
||||
|
||||
assert util.protocol_version(["0.9", "1.0"], (1, 0), (1, 1)) \
|
||||
== ((1, 0), (0, 9))
|
||||
assert util.protocol_version(["0.9", "1.1"], (1, 0), (1, 1)) \
|
||||
== ((1, 1), (0,9))
|
||||
assert util.protocol_version(["1.1", "0.9"], (1, 0), (1, 1)) \
|
||||
== (None, (1, 1))
|
||||
assert util.protocol_version(["0.8", "0.9"], (1, 0), (1, 1)) \
|
||||
== (None, (0, 8))
|
||||
assert util.protocol_version(["1.1", "1.2"], (1, 0), (1, 1)) \
|
||||
== ((1, 1), (1, 1))
|
||||
assert util.protocol_version(["1.2", "1.3"], (1, 0), (1, 1)) \
|
||||
== (None, (1, 2))
|
||||
|
||||
|
||||
def test_unpackers():
|
||||
b = bytes(range(256))
|
||||
assert util.unpack_le_int32_from(b, 0) == (50462976,)
|
||||
assert util.unpack_le_int32_from(b, 42) == (757869354,)
|
||||
assert util.unpack_le_int64_from(b, 0) == (506097522914230528,)
|
||||
assert util.unpack_le_int64_from(b, 42) == (3544384782113450794,)
|
||||
|
||||
assert util.unpack_le_uint16_from(b, 0) == (256,)
|
||||
assert util.unpack_le_uint16_from(b, 42) == (11050,)
|
||||
assert util.unpack_le_uint32_from(b, 0) == (50462976,)
|
||||
assert util.unpack_le_uint32_from(b, 42) == (757869354,)
|
||||
assert util.unpack_le_uint64_from(b, 0) == (506097522914230528,)
|
||||
assert util.unpack_le_uint64_from(b, 42) == (3544384782113450794,)
|
||||
|
||||
def test_hex_transforms():
|
||||
h = "AABBCCDDEEFF"
|
||||
assert util.hex_to_bytes(h) == b'\xaa\xbb\xcc\xdd\xee\xff'
|
||||
|
||||
|
||||
def test_pack_varint():
|
||||
tests = list(range(0, 258))
|
||||
tests.extend([1024, 65535, 65536, 4294967295, 4294967296, 8294967296])
|
||||
|
||||
for n in tests:
|
||||
data = util.pack_varint(n)
|
||||
deser = tx.Deserializer(data)
|
||||
assert deser._read_varint() == n
|
||||
|
||||
import struct
|
||||
with pytest.raises(struct.error):
|
||||
util.pack_varint(-1)
|
||||
assert util.pack_varint(0) == b'\0'
|
||||
assert util.pack_varint(5) == b'\5'
|
||||
assert util.pack_varint(252) == b'\xfc'
|
||||
assert util.pack_varint(253) == b'\xfd\xfd\0'
|
||||
assert util.pack_varint(65535) == b'\xfd\xff\xff'
|
||||
assert util.pack_varint(65536) == b'\xfe\0\0\1\0'
|
||||
assert util.pack_varint(2**32-1) == b'\xfe\xff\xff\xff\xff'
|
||||
assert util.pack_varint(2**32) == b'\xff\0\0\0\0\1\0\0\0'
|
||||
assert util.pack_varint(2**64-1) \
|
||||
== b'\xff\xff\xff\xff\xff\xff\xff\xff\xff'
|
||||
|
||||
def test_pack_varbytes():
|
||||
tests = [b'', b'1', b'2' * 253, b'3' * 254, b'4' * 256, b'5' * 65536]
|
||||
|
||||
for test in tests:
|
||||
data = util.pack_varbytes(test)
|
||||
deser = tx.Deserializer(data)
|
||||
assert deser._read_varbytes() == test
|
||||
|
||||
def test_json_serialize_deserialize():
|
||||
obj = {
|
||||
'coin': 'Bitcoin',
|
||||
'height': 950000,
|
||||
'counts': {'getblock': 2},
|
||||
'nested': {'list': [1, 2, 3], 'flag': True, 'none': None},
|
||||
}
|
||||
serialized = util.json_serialize(obj)
|
||||
assert isinstance(serialized, str)
|
||||
assert util.json_deserialize(serialized) == {
|
||||
'coin': 'Bitcoin',
|
||||
'height': 950000,
|
||||
'counts': {'getblock': 2},
|
||||
'nested': {'list': [1, 2, 3], 'flag': True, 'none': None},
|
||||
}
|
||||
Reference in new issue
Block a user