Skip to content

Commit

Permalink
Update functional tests (#29)
Browse files Browse the repository at this point in the history
  • Loading branch information
bytzck authored and watto-engineer committed Dec 30, 2022
1 parent 0bcd8ea commit 51117ef
Show file tree
Hide file tree
Showing 23 changed files with 421 additions and 80 deletions.
4 changes: 2 additions & 2 deletions test/functional/feature_dip3_deterministicmns.py
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ def prepare_mn(self, node, idx, alias):

def create_mn_collateral(self, node, mn):
mn.collateral_address = node.getnewaddress()
mn.collateral_txid = node.sendtoaddress(mn.collateral_address, 1000)
mn.collateral_txid = node.sendtoaddress(mn.collateral_address, 25000)
mn.collateral_vout = None
node.generate(1)

Expand All @@ -239,7 +239,7 @@ def create_mn_collateral(self, node, mn):

# register a protx MN and also fund it (using collateral inside ProRegTx)
def register_fund_mn(self, node, mn):
node.sendtoaddress(mn.fundsAddr, 1000.001)
node.sendtoaddress(mn.fundsAddr, 25000.001)
mn.collateral_address = node.getnewaddress()
mn.rewards_address = node.getnewaddress()

Expand Down
29 changes: 16 additions & 13 deletions test/functional/feature_llmq_data_recovery.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@

class QuorumDataRecoveryTest(WagerrTestFramework):
def set_test_params(self):
extra_args = [["-vbparams=dip0020:0:999999999999:10:8:6:5"] for _ in range(9)]
extra_args = [["-sporkkey=TKCjZUMw7Hjq5vUSKdcuQnotxcG9De2oxH", "-minrelaytxfee=0.00002"] for _ in range(9)]
self.set_wagerr_test_params(9, 7, fast_dip3_enforcement=True, extra_args=extra_args)
self.set_wagerr_llmq_test_params(4, 3)

Expand Down Expand Up @@ -125,44 +125,47 @@ def run_test(self):
node.sporkupdate("SPORK_21_QUORUM_ALL_CONNECTED", 0)
self.wait_for_sporks_same()
self.activate_dip8()

height = self.nodes[0].getblockcount()
while height < 300:
self.nodes[0].generate(1)
height = self.nodes[0].getblockcount()
logger.info("Test automated DGK data recovery")
# This two nodes will remain the only ones with valid DKG data
last_resort_test = None
last_resort_v17 = None
last_resort_dip0020 = None
while True:
# Mine the quorums used for the recovery test
quorum_hash_recover = self.mine_quorum()
# Get all their member masternodes
member_mns_recover_test = self.get_member_mns(llmq_test, quorum_hash_recover)
member_mns_recover_v17 = self.get_member_mns(llmq_test_v17, quorum_hash_recover)
member_mns_recover_dip0020 = self.get_member_mns(llmq_test_v17, quorum_hash_recover)
# All members should initially be valid
self.test_mns(llmq_test, quorum_hash_recover, valid_mns=member_mns_recover_test)
self.test_mns(llmq_test_v17, quorum_hash_recover, valid_mns=member_mns_recover_v17)
self.test_mns(llmq_test_v17, quorum_hash_recover, valid_mns=member_mns_recover_dip0020)
try:
# As last resorts find one node which is in llmq_test but not in llmq_test_v17 and one other vice versa
last_resort_test = self.get_subset_only_in_left(member_mns_recover_test, member_mns_recover_v17)[0]
last_resort_v17 = self.get_subset_only_in_left(member_mns_recover_v17, member_mns_recover_test)[0]
last_resort_test = self.get_subset_only_in_left(member_mns_recover_test, member_mns_recover_dip0020)[0]
last_resort_dip0020 = self.get_subset_only_in_left(member_mns_recover_dip0020, member_mns_recover_test)[0]
break
except IndexError:
continue
assert last_resort_test != last_resort_v17
assert last_resort_test != last_resort_dip0020
# Reindex all other nodes the to drop their DKG data, first run with recovery disabled to make sure disabling
# works as expected
recover_members = member_mns_recover_test + member_mns_recover_v17
exclude_members = [last_resort_test, last_resort_v17]
recover_members = member_mns_recover_test + member_mns_recover_dip0020
exclude_members = [last_resort_test, last_resort_dip0020]
# Reindex all masternodes but exclude the last_resort for both testing quorums
self.restart_mns(exclude=exclude_members, reindex=True, qdata_recovery_enabled=False)
# Validate all but one are invalid members now
self.test_mns(llmq_test, quorum_hash_recover, valid_mns=[last_resort_test], all_mns=member_mns_recover_test)
self.test_mns(llmq_test_v17, quorum_hash_recover, valid_mns=[last_resort_v17], all_mns=member_mns_recover_v17)
self.test_mns(llmq_test_v17, quorum_hash_recover, valid_mns=[last_resort_dip0020], all_mns=member_mns_recover_dip0020)
# If recovery would be enabled it would trigger after the mocktime bump / mined block
self.bump_mocktime(self.quorum_data_request_expiration_timeout + 1)
node.generate(1)
time.sleep(10)
# Make sure they are still invalid
self.test_mns(llmq_test, quorum_hash_recover, valid_mns=[last_resort_test], all_mns=member_mns_recover_test)
self.test_mns(llmq_test_v17, quorum_hash_recover, valid_mns=[last_resort_v17], all_mns=member_mns_recover_v17)
self.test_mns(llmq_test_v17, quorum_hash_recover, valid_mns=member_mns_recover_dip0020, recover=True)
# Mining a block should not result in a chainlock now because the responsible quorum shouldn't have enough
# valid members.
self.wait_for_chainlocked_block(node, node.generate(1)[0], False, 5)
Expand All @@ -171,7 +174,7 @@ def run_test(self):
# Validate that all invalid members recover. Note: recover=True leads to mocktime bumps and mining while waiting
# which trigger CQuorumManger::TriggerQuorumDataRecoveryThreads()
self.test_mns(llmq_test, quorum_hash_recover, valid_mns=member_mns_recover_test, recover=True)
self.test_mns(llmq_test_v17, quorum_hash_recover, valid_mns=member_mns_recover_v17, recover=True)
self.test_mns(llmq_test_v17, quorum_hash_recover, valid_mns=member_mns_recover_dip0020, recover=True)
# Mining a block should result in a chainlock now because the quorum should be healed
self.wait_for_chainlocked_block_all_nodes(node.getbestblockhash())
logger.info("Test -llmq-qvvec-sync command line parameter")
Expand Down
1 change: 1 addition & 0 deletions test/functional/feature_llmq_signing.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
from test_framework.test_framework import WagerrTestFramework
from test_framework.util import assert_equal, assert_raises_rpc_error, connect_nodes, force_finish_mnsync, hex_str_to_bytes, wait_until

WAGERR_AUTH_ADDR = "TqMgq4qkw7bGxf6CDhtDfEqzEtWD5C7x8U"

class LLMQSigningTest(WagerrTestFramework):
def set_test_params(self):
Expand Down
1 change: 1 addition & 0 deletions test/functional/feature_logging.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#!/usr/bin/env python3
# Copyright (c) 2017 The Bitcoin Core developers
# Copyright (c) 2018-2021 The Wagerr Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
"""Test debug logging."""
Expand Down
45 changes: 23 additions & 22 deletions test/functional/feature_multikeysporks.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#!/usr/bin/env python3
# Copyright (c) 2018-2021 The Dash Core developers
# Copyright (c) 2018-2021 The Wagerr Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
Expand All @@ -25,43 +26,43 @@ def set_test_params(self):
self.setup_clean_chain = True

def setup_network(self):
# secret(base58): 931wyuRNVYvhg18Uu9bky5Qg1z4QbxaJ7fefNBzjBPiLRqcd33F

# secret(base58): NNaCsaiaNDc5GFEp8bXVngvxeKazj7HVPXH8n6ywHWrDRomj4yor
# keyid(hex): 60f0f57f71f0081f1aacdd8432340a33a526f91b
# address(base58): yNsMZhEhYqv14TgdYb1NS2UmNZjE8FSJxa
# address(base58): TZMsX7b1FAjJvnP78y7ChjpSMZ1N2zCDGt

# secret(base58): 91vbXGMSWKGHom62986XtL1q2mQDA12ngcuUNNe5NfMSj44j7g3
# secret(base58): NQhNc5UpCiPRrwE6HvnYuHz7i8aNwUm6QoMv5xUPk7HWsfSupVjq
# keyid(hex): 43dff2b09de2f904f688ec14ee6899087b889ad0
# address(base58): yfLSXFfipnkgYioD6L8aUNyfRgEBuJv48h
# address(base58): TxWap683gHnERvK86W4DNZUHPeaR8XvSXx

# secret(base58): 92bxUjPT5AhgXuXJwfGGXqhomY2SdQ55MYjXyx9DZNxCABCSsRH
# secret(base58): NRzqHHPT5NHy4NZhfNqGj3w4JLyU7KGGFKTja6vx5KoTsaCVZvwZ
# keyid(hex): d9aa5fa00cce99101a4044e65dc544d1579890de
# address(base58): ygcG5S2pQz2U1UAaHvU6EznKZW7yapKMA7
# address(base58): TxSr9mDxoC4u4Q1UqqzWvnQzvMWYyiYeeQ

# secret(base58): 934yPXiVGf4RCY2qTs2Bt5k3TEtAiAg12sMxCt8yVWbSU7p3fuD
# secret(base58): NPo1astJDM7LEDkUVViqScS2oXmxGGGxpKTQjDanYRqYyXV6jcPE
# keyid(hex): 0b23935ce0bea3b997a334f6fa276c9fa17687b2
# address(base58): ycbRQWbovrhQMTuxg9p4LAuW5SCMAKqPrn
# address(base58): TxCQxNd4qmJJjREV8cf6GgRDWd69KGh5G9

# secret(base58): 92Cxwia363Wg2qGF1fE5z4GKi8u7r1nrWQXdtsj2ACZqaDPSihD
# secret(base58): NJeFmk3hhB8PKoYSE9R5RKqcEyqFiKmjPtQmHitxgifAJtRdUZ7M
# keyid(hex): 1d1098b2b1f759b678a0a7a098637a9b898adcac
# address(base58): yc5TGfcHYoLCrcbVy4umsiDjsYUn39vLui
# address(base58): Tx2n9FNwoNCKdCUtfbnqLcLgPao3bpGjCp

self.add_nodes(5)

spork_chain_params = ["-sporkaddr=ygcG5S2pQz2U1UAaHvU6EznKZW7yapKMA7",
"-sporkaddr=yfLSXFfipnkgYioD6L8aUNyfRgEBuJv48h",
"-sporkaddr=yNsMZhEhYqv14TgdYb1NS2UmNZjE8FSJxa",
"-sporkaddr=ycbRQWbovrhQMTuxg9p4LAuW5SCMAKqPrn",
"-sporkaddr=yc5TGfcHYoLCrcbVy4umsiDjsYUn39vLui",
"-minsporkkeys=3"]
spork_chain_params = ["-sporkaddr=TxSr9mDxoC4u4Q1UqqzWvnQzvMWYyiYeeQ",
"-sporkaddr=TxWap683gHnERvK86W4DNZUHPeaR8XvSXx",
"-sporkaddr=TZMsX7b1FAjJvnP78y7ChjpSMZ1N2zCDGt",
"-sporkaddr=TxCQxNd4qmJJjREV8cf6GgRDWd69KGh5G9",
"-sporkaddr=Tx2n9FNwoNCKdCUtfbnqLcLgPao3bpGjCp",
"-minsporkkeys=3"]

# Node0 extra args to use on normal node restarts
self.node0_extra_args = ["-sporkkey=931wyuRNVYvhg18Uu9bky5Qg1z4QbxaJ7fefNBzjBPiLRqcd33F"] + spork_chain_params
self.node0_extra_args = ["-sporkkey=NNaCsaiaNDc5GFEp8bXVngvxeKazj7HVPXH8n6ywHWrDRomj4yor"] + spork_chain_params

self.start_node(0, self.node0_extra_args)
self.start_node(1, ["-sporkkey=91vbXGMSWKGHom62986XtL1q2mQDA12ngcuUNNe5NfMSj44j7g3"] + spork_chain_params)
self.start_node(2, ["-sporkkey=92bxUjPT5AhgXuXJwfGGXqhomY2SdQ55MYjXyx9DZNxCABCSsRH"] + spork_chain_params)
self.start_node(3, ["-sporkkey=934yPXiVGf4RCY2qTs2Bt5k3TEtAiAg12sMxCt8yVWbSU7p3fuD"] + spork_chain_params)
self.start_node(4, ["-sporkkey=92Cxwia363Wg2qGF1fE5z4GKi8u7r1nrWQXdtsj2ACZqaDPSihD"] + spork_chain_params)
self.start_node(1, ["-sporkkey=NQhNc5UpCiPRrwE6HvnYuHz7i8aNwUm6QoMv5xUPk7HWsfSupVjq"] + spork_chain_params)
self.start_node(2, ["-sporkkey=NRzqHHPT5NHy4NZhfNqGj3w4JLyU7KGGFKTja6vx5KoTsaCVZvwZ"] + spork_chain_params)
self.start_node(3, ["-sporkkey=NPo1astJDM7LEDkUVViqScS2oXmxGGGxpKTQjDanYRqYyXV6jcPE"] + spork_chain_params)
self.start_node(4, ["-sporkkey=NJeFmk3hhB8PKoYSE9R5RKqcEyqFiKmjPtQmHitxgifAJtRdUZ7M"] + spork_chain_params)

# connect nodes at start
for i in range(0, 5):
Expand Down
4 changes: 2 additions & 2 deletions test/functional/feature_new_quorum_type_activation.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
'''
feature_new_quorum_type_activation.py
Tests the activation of a new quorum type in v17 via a bip9-like hardfork
Tests the activation of a new quorum type in dip0020 via a bip9-like hardfork
'''

Expand All @@ -26,7 +26,7 @@ def run_test(self):
ql = self.nodes[0].quorum("list")
assert_equal(len(ql), 2)
assert "llmq_test_v17" not in ql
self.nodes[0].generate(10)
self.nodes[0].generate(300)
assert_equal(get_bip9_status(self.nodes[0], 'dip0020')['status'], 'locked_in')
ql = self.nodes[0].quorum("list")
assert_equal(len(ql), 2)
Expand Down
142 changes: 142 additions & 0 deletions test/functional/feature_startmn.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
#!/usr/bin/env python3
# Copyright (c) 2014-2016 The Bitcoin Core developers
# Copyright (c) 2021 The Wagerr Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
"""Test the wallet."""
import sys

from test_framework.test_framework import WagerrTestFramework
from test_framework.util import *
from test_framework.blocktools import *


class WalletTest(WagerrTestFramework):
def set_test_params(self):
self.num_nodes = 2
self.setup_clean_chain = True
self.extra_args = [['-sporkkey=TKCjZUMw7Hjq5vUSKdcuQnotxcG9De2oxH'],[]]

def setup_network(self):
self.add_nodes(2, self.extra_args, stderr=sys.stdout)
self.start_node(0)
self.start_node(1)
connect_nodes_bi(self.nodes,0,1)
self.sync_all(self.nodes[0:1])

def run_test(self):
self.log.info("Importing token management privkey...")
self.nodes[0].importprivkey("TKCjZUMw7Hjq5vUSKdcuQnotxcG9De2oxH")
privkey = self.nodes[0].dumpprivkey("TqMgq4qkw7bGxf6CDhtDfEqzEtWD5C7x8U")
assert_equal(privkey, "TKCjZUMw7Hjq5vUSKdcuQnotxcG9De2oxH")

self.log.info("Mining blocks...")
self.nodes[0].generate(16)

inputs = [ ]
outputs = { self.nodes[0].getnewaddress() : 15000000, self.nodes[0].getnewaddress() : 15000000, self.nodes[0].getnewaddress() : 15000000, self.nodes[0].getnewaddress() : 15000000, self.nodes[0].getnewaddress() : 15000000, self.nodes[0].getnewaddress() : 15000000 }
rawtx = self.nodes[0].createrawtransaction(inputs, outputs)
rawtxfund = self.nodes[0].fundrawtransaction(rawtx)['hex']
tx = FromHex(CTransaction(), rawtxfund)
tx_signed = self.nodes[0].signrawtransactionwithwallet(ToHex(tx))["hex"]
self.nodes[0].sendrawtransaction(tx_signed)

self.nodes[0].generate(300)

self.log.info("Funding token management address...")
self.nodes[0].sendtoaddress("TqMgq4qkw7bGxf6CDhtDfEqzEtWD5C7x8U", 1)

self.log.info("Mining blocks...")
self.nodes[0].generate(1)

# configuremanagementtoken MGT Management https://www.google.com 0 4 906e74f8d70d3dcadd4523c5c217360880f8b311292fcd4e39da6fd8d1fd14b36d27abe642483f2ff4c0ed492c707db9 false true
self.log.info("Create MGT token...")
mgtBLSKey = self.nodes[0].bls("generate")
self.log.info("mgtBLSKey:")
self.log.info(mgtBLSKey)
mgtConfig = self.nodes[0].configuremanagementtoken("MGT", "Management", "https://www.google.com", "4f92d91db24bb0b8ca24a2ec86c4b012ccdc4b2e9d659c2079f5cc358413a765", "4", mgtBLSKey['public'], "false", "true")
self.nodes[0].generate(1)
self.log.info("mgtConfig:")
self.log.info(mgtConfig)
tokensaddress=self.nodes[0].getnewaddress()
self.log.info("tokensaddress: "+tokensaddress)
self.nodes[0].minttoken(mgtConfig['groupID'], tokensaddress, 20)
self.nodes[0].generate(1)

self.log.info("Create GVT token...")
gvtBLSKey = self.nodes[0].bls("generate")
self.log.info("gvtBLSKey:")
self.log.info(gvtBLSKey)
gvtConfig = self.nodes[0].configuremanagementtoken("GVT", "GuardianValidatorToken", "https://www.google.com", "4f92d91db24bb0b8ca24a2ec86c4b012ccdc4b2e9d659c2079f5cc358413a765", "0", gvtBLSKey['public'], "true", "true")
self.nodes[0].generate(1)
self.log.info("gvtConfig:")
self.log.info(gvtConfig)
self.nodes[0].minttoken(gvtConfig['groupID'], tokensaddress, 30)
self.nodes[0].generate(1)
GVTcreditID = self.nodes[0].getsubgroupid(gvtConfig['groupID'], "credit")
self.log.info("GVTcreditID:")
self.log.info(GVTcreditID)
GCTcreditMint=self.nodes[0].minttoken(GVTcreditID, tokensaddress, 100)
self.log.info("GCTcreditMint:")
self.log.info(GCTcreditMint)
self.nodes[0].generate(1)

tokenbalance = self.nodes[0].gettokenbalance()
self.log.info("tokenbalance:")
self.log.info(tokenbalance)

self.sync_all(self.nodes[0:1])

mn01_collateral_address = self.nodes[0].getnewaddress()
mn01_p2p_port = p2p_port(0)
mn01_blsKey = self.nodes[0].bls('generate')
mn01_fundsAddr = self.nodes[0].getnewaddress()
mn01_ownerAddr = self.nodes[0].getnewaddress()
mn01_operatorAddr = mn01_blsKey['public']
mn01_votingAddr = mn01_ownerAddr
# mn01_blsMnkey = mn01_blsKey['secret']

self.nodes[0].sendtoaddress(mn01_fundsAddr, 10000000.001)
self.nodes[0].sendtoken(GVTcreditID, mn01_fundsAddr, 1)
self.nodes[0].generate(1)
mn01_collateral_address = self.nodes[0].getnewaddress()
mn01_rewards_address = self.nodes[0].getnewaddress()

self.log.info(mn01_collateral_address)
self.log.info('127.0.0.1:%d' % mn01_p2p_port)
self.log.info(mn01_ownerAddr)
self.log.info(mn01_operatorAddr)
self.log.info(mn01_votingAddr)
self.log.info(mn01_rewards_address)
self.log.info(mn01_fundsAddr)

mn01_protx_hash = self.nodes[0].protx('register_fund', mn01_collateral_address, '127.0.0.1:%d' % mn01_p2p_port, mn01_ownerAddr, mn01_operatorAddr, mn01_votingAddr, 0, mn01_rewards_address, mn01_fundsAddr)

mn01_collateral_txid = mn01_protx_hash
mn01_collateral_vout = -1

rawtx = self.nodes[0].getrawtransaction(mn01_collateral_txid, 1)
for txout in rawtx['vout']:
if txout['value'] == Decimal(10000000):
mn01_collateral_vout = txout['n']
break
assert(mn01_collateral_vout != -1)

self.log.info("mn01_protx_hash:")
self.log.info(mn01_protx_hash)

self.sync_all()
self.nodes[0].spork("SPORK_4_DIP0003_ENFORCED", self.nodes[0].getblockcount() + 1)
self.wait_for_sporks_same()
self.sync_all()

self.nodes[0].generate(2)

self.log.info(self.nodes[0].masternode('list'))

def cutoff(self):
self.log.info("Done")


if __name__ == '__main__':
WalletTest().main()
7 changes: 4 additions & 3 deletions test/functional/feature_txindex.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#!/usr/bin/env python3
# Copyright (c) 2014-2015 The Bitcoin Core developers
# Copyright (c) 2021 The Wagerr Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.

Expand Down Expand Up @@ -52,7 +53,7 @@ def run_test(self):
scriptPubKey = CScript([OP_DUP, OP_HASH160, addressHash, OP_EQUALVERIFY, OP_CHECKSIG])
unspent = self.nodes[0].listunspent()
tx = CTransaction()
tx_fee_sat = 1000
tx_fee_sat = 1600
amount = int(unspent[0]["amount"] * 100000000) - tx_fee_sat
tx.vin = [CTxIn(COutPoint(int(unspent[0]["txid"], 16), unspent[0]["vout"]))]
tx.vout = [CTxOut(amount, scriptPubKey)]
Expand All @@ -65,8 +66,8 @@ def run_test(self):

# Check verbose raw transaction results
verbose = self.nodes[3].getrawtransaction(txid, 1)
assert_equal(verbose["vout"][0]["valueSat"], 50000000000 - tx_fee_sat)
assert_equal(verbose["vout"][0]["value"] * 100000000, 50000000000 - tx_fee_sat)
assert_equal(verbose["vout"][0]["valueSat"], 1000000000000 - tx_fee_sat)
assert_equal(verbose["vout"][0]["value"] * 100000000, 1000000000000 - tx_fee_sat)

self.log.info("Passed")

Expand Down
Loading

0 comments on commit 51117ef

Please sign in to comment.