Example #1
0
 def sc_setup_chain(self):
     mc_node_1 = self.nodes[0]
     sc_node_1_configuration = SCNodeConfiguration(
         MCConnectionInfo(address="ws://{0}:{1}".format(mc_node_1.hostname, websocket_port_by_mc_node_index(0)))
     )
     network = SCNetworkConfiguration(SCCreationInfo(mc_node_1, 600, 1000), sc_node_1_configuration)
     self.sc_nodes_bootstrap_info = bootstrap_sidechain_nodes(self.options.tmpdir, network)
    def sc_setup_chain(self):
        # Bootstrap new SC, specify SC node 1 connection to MC node 1
        mc_node_1 = self.nodes[0]
        sc_node_1_configuration = SCNodeConfiguration(
            MCConnectionInfo(address="ws://{0}:{1}".format(mc_node_1.hostname, websocket_port_by_mc_node_index(0)))
        )
        sc_node_2_configuration = SCNodeConfiguration(MCConnectionInfo(), False)

        network = SCNetworkConfiguration(SCCreationInfo(mc_node_1, 600, 1000),
                                         sc_node_1_configuration, sc_node_2_configuration)
        bootstrap_sidechain_nodes(self.options.tmpdir, network)
    def sc_setup_chain(self):
        # Bootstrap new SC, specify SC nodes connection to MC node
        mc_node_1 = self.nodes[0]
        sc_node_1_configuration = SCNodeConfiguration(
            MCConnectionInfo(address="ws://{0}:{1}".format(
                mc_node_1.hostname, websocket_port_by_mc_node_index(0))))
        sc_node_2_configuration = SCNodeConfiguration(
            MCConnectionInfo(address="ws://{0}:{1}".format(
                mc_node_1.hostname, websocket_port_by_mc_node_index(0))))

        network = SCNetworkConfiguration(SCCreationInfo(mc_node_1, 100, 1000),
                                         sc_node_1_configuration,
                                         sc_node_2_configuration)
        # rewind sc genesis block timestamp for 5 consensus epochs
        self.sc_nodes_bootstrap_info = bootstrap_sidechain_nodes(
            self.options.tmpdir, network, 720 * 120 * 5)
    def run_test(self):
        mc_node = self.nodes[0]
        mc_node.generate(200)

        # Generate MC Block without sidechains.
        block_id = mc_node.generate(1)[0]
        block_hex = mc_node.getblock(block_id, False)
        block_json = mc_node.getblock(block_id)

        print(
            "MC Block without SC data: \nHash = {0}\nHex = {1}\nJson = {2}\n".
            format(str(block_id), str(block_hex), str(block_json)))

        # Generate MC block with 3 sidechains mentioned.
        sc_creation_info = SCCreationInfo(mc_node, 100, 1000)
        boot_info = create_sidechain(sc_creation_info)
        sidechain_id_1 = str(boot_info.sidechain_id)

        boot_info = create_sidechain(sc_creation_info)
        sidechain_id_2 = str(boot_info.sidechain_id)

        boot_info = create_sidechain(sc_creation_info)
        sidechain_id_3 = str(boot_info.sidechain_id)

        sc_address = "000000000000000000000000000000000000000000000000000000000000add1"
        # Send 3 FTs to different sidechains
        mc_node.sc_send(sc_address, 1, sidechain_id_1)  # 1 Zen
        mc_node.sc_send(sc_address, 2, sidechain_id_2)  # 2 Zen
        mc_node.sc_send(sc_address, 3, sidechain_id_3)  # 3 Zen
        # Generate block
        block_id = mc_node.generate(1)[0]
        block_hex = mc_node.getblock(block_id, False)
        block_json = mc_node.getblock(block_id)
        # Note: we sort only 2 last characters, so almost equal to the sort of the little-endian bytes
        sidechain_ids = [sidechain_id_1, sidechain_id_2, sidechain_id_3]
        sorted_sidechain_ids = sorted(sidechain_ids, key=lambda x: x[-2:])
        print(
            "MC Block with multiple SCs mentioned: \nHash = {0}\nHex = {1}\nJson = {2}\nSidechains = {3}\n"
            .format(str(block_id), str(block_hex), str(block_json),
                    sorted_sidechain_ids))
Example #5
0
    def run_test(self):
        coin = 100000000
        # Activate Sidechains fork
        mc_node = self.nodes[0]
        mc_node_miner = self.nodes[1]
        mc_node.generate(
            20
        )  # Generate first 20 block by main MC node to get some reward coins
        self.sync_all()
        mc_node_miner.generate(200)  # Generate the rest by another node.
        self.sync_all()
        print("MC Node started.")

        mc_height = mc_node.getblockcount()
        print("MC chain height is " + str(mc_height) +
              ". Sidechains fork activated.\n")

        self.pause()

        # Declare SC creation output tx
        print("\nDeclaring new Sidechain in MC network.")
        sc_node_configuration = SCNodeConfiguration(
            MCConnectionInfo(address="ws://{0}:{1}".format(
                mc_node.hostname, websocket_port_by_mc_node_index(0))))

        creation_amount = 100  # Zen
        withdrawal_epoch_length = 10
        sc_creation_info = SCCreationInfo(mc_node, creation_amount,
                                          withdrawal_epoch_length)
        accounts = generate_secrets("seed", 1)
        vrf_keys = generate_vrf_secrets("seed", 1)
        genesis_account = accounts[0]
        vrf_key = vrf_keys[0]
        certificate_proof_info = generate_certificate_proof_info("seed", 7, 5)

        custom_data = vrf_key.publicKey
        print(
            "Running sc_create RPC call on MC node:\n" +
            'sc_create {} "{}" {} "{}" "{}" "{}"'.format(
                withdrawal_epoch_length, genesis_account.publicKey,
                sc_creation_info.forward_amount,
                certificate_proof_info.verificationKey, custom_data,
                certificate_proof_info.genSysConstant))
        print(
            "where arguments are:\nwithdrawal epoch length - {}\nfirst Forward Transfer receiver address in the Sidechain - {}\nfirst Forward Transfer amount - {} ({} Zen)\nwithdrawal certificate verification key - {}\nfirst ForgerBox VRF publick key - {}\nwithdrawal certificate Snark proof public input - {}\n"
            .format(withdrawal_epoch_length, genesis_account.publicKey,
                    sc_creation_info.forward_amount * coin,
                    sc_creation_info.forward_amount,
                    certificate_proof_info.verificationKey, custom_data,
                    certificate_proof_info.genSysConstant))

        self.pause()

        # Create Tx and Block
        sc_create_res = mc_node.sc_create(
            withdrawal_epoch_length, genesis_account.publicKey,
            sc_creation_info.forward_amount,
            certificate_proof_info.verificationKey, custom_data,
            certificate_proof_info.genSysConstant)

        transaction_id = sc_create_res["txid"]
        print "Sidechain creation transaction Id - {0}".format(transaction_id)

        sidechain_id = sc_create_res["scid"]
        print "Sidechain created with Id -  {0}\n".format(sidechain_id)

        print "Generating Block with sidechain creation transaction..."
        block_id = mc_node.generate(1)[0]
        print "Block id - {}\n".format(block_id)

        self.pause()

        # Declare SC genesis data config info
        print("\nPreparing Sidechain network configuration.")
        print(
            "Running getscgenesisinfo RPC call on MC to get the Sidechain related data for genesis block generation:\n"
            + 'getscgenesisinfo "{}"'.format(sidechain_id))

        genesis_info = [
            mc_node.getscgenesisinfo(sidechain_id),
            mc_node.getblockcount(), sidechain_id
        ]

        jsonParameters = {
            "secret": genesis_account.secret,
            "vrfSecret": vrf_key.secret,
            "info": genesis_info[0]
        }
        jsonNode = launch_bootstrap_tool("genesisinfo", jsonParameters)
        print(
            "\nCalculating Sidechain network genesis data using ScBootstrappingTool command:\n"
            + "genesisinfo {}\n".format(
                json.dumps(jsonParameters, indent=4, sort_keys=True)) +
            "where arguments are:\ninfo - genesis info retrieved from MC on previous step\nsecret and vrfSecret - private part the corresponds first FT data in sc_create RPC call.\n"
        )

        self.pause()

        # Result of genesis data config info
        print("Result:\n {}".format(
            json.dumps(jsonNode, indent=4, sort_keys=True)))
        genesis_data = jsonNode

        sidechain_id = genesis_info[2]

        sc_bootstrap_info = SCBootstrapInfo(
            sidechain_id, genesis_account, sc_creation_info.forward_amount,
            genesis_info[1], genesis_data["scGenesisBlockHex"],
            genesis_data["powData"], genesis_data["mcNetwork"],
            sc_creation_info.withdrawal_epoch_length, vrf_key,
            certificate_proof_info)

        bootstrap_sidechain_node(self.options.tmpdir, 0, sc_bootstrap_info,
                                 sc_node_configuration)

        self.pause()

        # Start SC info
        print("\nStarting Sidechain node...")
        self.sc_nodes = start_sc_nodes(1,
                                       self.options.tmpdir,
                                       print_output_to_file=True)

        sc_node = self.sc_nodes[0]

        initial_sc_balance = sc_node.wallet_balance()["result"]
        print("\nInitial SC wallet balance in satoshi: {}".format(
            json.dumps(initial_sc_balance, indent=4, sort_keys=True)))

        initial_boxes_balances = sc_node.wallet_allBoxes()["result"]
        print("\nInitial SC wallet boxes: {}".format(
            json.dumps(initial_boxes_balances, indent=4, sort_keys=True)))

        self.pause()

        # MC balance before FT
        print("\n MC total balance before Forward Transfer is {} Zen".format(
            mc_node.getbalance()))

        self.pause()

        # Do FT
        sc_address = sc_node.wallet_createPrivateKey25519(
        )["result"]["proposition"]["publicKey"]
        ft_amount = 5
        print(
            "\nCreating Forward Transfer with {} satoshi ({} Zen) to Sidechain:\n"
            .format(ft_amount * coin, ft_amount) +
            'sc_send "{}" {} "{}"'.format(sc_address, ft_amount,
                                          sc_bootstrap_info.sidechain_id))

        self.pause()

        ft_tx_id = mc_node.sc_send(sc_address, ft_amount,
                                   sc_bootstrap_info.sidechain_id)
        print("\nFT transaction id - {}".format(ft_tx_id))

        # Generate MC block and SC block and check that FT appears in SC node wallet
        print "Generating MC Block with Forward Transfer..."
        self.sync_all()
        mcblock_hash1 = mc_node_miner.generate(1)[0]
        self.sync_all()
        print "MC Block id - {}\n".format(mcblock_hash1)
        print "Generating SC Block to include MC Block Forward Transfer..."
        scblock_id1 = generate_next_blocks(sc_node, "first node", 1)[0]

        self.pause()

        # MC balance after FT
        print("\n MC total balance after Forward Transfer is {} Zen".format(
            mc_node.getbalance()))

        self.pause()

        # Check balance changes
        sc_balance = sc_node.wallet_balance()["result"]
        print("\nSC wallet balance in satoshi: {}".format(
            json.dumps(sc_balance, indent=4, sort_keys=True)))

        boxes_balances = sc_node.wallet_allBoxes()["result"]
        print("\nSC wallet boxes: {}".format(
            json.dumps(boxes_balances, indent=4, sort_keys=True)))

        self.pause()

        # Do inchain coins send
        sc_send_amount = 1  # Zen
        print("\nSending {} satoshi ({} Zen) inside sidechain...".format(
            sc_send_amount * coin, sc_send_amount))
        sc_address = sc_node.wallet_allPublicKeys(
        )["result"]["propositions"][-1]["publicKey"]
        print(sc_address)
        self.send_coins(sc_node, sc_address, sc_send_amount * coin, 100)

        print "Generating SC Block with send coins transaction..."
        scblock_id2 = generate_next_blocks(sc_node, "first node", 1)[0]

        self.pause()

        # Check balance changes
        sc_balance = sc_node.wallet_balance()["result"]
        print("\nSC wallet balance in satoshi: {}".format(
            json.dumps(sc_balance, indent=4, sort_keys=True)))

        boxes_balances = sc_node.wallet_allBoxes()["result"]
        print("\nSC wallet boxes: {}".format(
            json.dumps(boxes_balances, indent=4, sort_keys=True)))

        # Do BT
        self.pause()
        mc_address = mc_node.getnewaddress("")
        bt_amount = 2  # Zen
        withdrawal_request = {
            "outputs": [{
                "publicKey": mc_address,
                "value": bt_amount * coin
            }]
        }

        print(
            "\nCreating Backward Transfer request to withdraw {} satoshi ({} Zen) to the Mainchain..."
            .format(bt_amount * coin, bt_amount))
        sc_node.transaction_withdrawCoins(json.dumps(withdrawal_request))

        print "Generating SC Block with Backward Transfer request transaction..."
        scblock_id3 = generate_next_blocks(sc_node, "first node", 1)[0]

        self.pause()

        # Run block generation till epoch end -> automatic block generation
        print(
            "Generating 9 more MC blocks to finish withdrawal epoch for the Sidechain..."
        )
        mc_block_ids = mc_node.generate(9)
        print "MC Block ids - {}\n".format(mc_block_ids)
        print(
            "Generating SC blocks to synchronize MC blocks and automatically start creation of Withdrawal Certificate..."
        )
        sc_block_ids = generate_next_blocks(sc_node, "first node", 4)
        print("\nGenerating Withdrawal Certificate...\n")

        attempts = 20
        while mc_node.getmempoolinfo()["size"] == 0 and attempts > 0:
            if attempts % 4 == 0:
                print("Wait for withdrawal certificate in MC memory pool...")
            time.sleep(10)
            attempts -= 1
        assert_equal(1,
                     mc_node.getmempoolinfo()["size"],
                     "Certificate was not added to Mc node mmepool.")

        certHash = mc_node.getrawmempool()[0]
        print("Withdrawal certificate hash - " + certHash)
        cert = mc_node.getrawcertificate(certHash, 1)
        print("Withdrawal certificate - {}".format(
            json.dumps(cert, indent=4, sort_keys=True, default=str)))

        self.pause()

        # Check MC balance for BT destination address before Certificate inclusion
        mc_balance_before_cert = mc_node.getreceivedbyaddress(mc_address)
        print(
            "\nMC address {} balance before Certificate inclusion is = {:.8f} Zen."
            .format(mc_address, mc_balance_before_cert))

        self.pause()

        # Generate MC block to include the certificate
        print(
            "\nGenerating 1 more MC block to include Withdrawal certificate in the chain..."
        )
        mc_block_4 = mc_node.generate(1)[0]
        print "MC Block id - {}\n".format(mc_block_4)

        self.pause()

        # Check MC balance for BT destination address before Certificate inclusion
        mc_balance_after_cert = mc_node.getreceivedbyaddress(mc_address)
        print(
            "\nMC address {} balance after Certificate inclusion is = {:.8f} Zen."
            .format(mc_address, mc_balance_after_cert))

        self.pause()

        # Get SC balances changes
        sc_balance = sc_node.wallet_balance()["result"]
        print("\nSC wallet balance in satoshi: {}".format(
            json.dumps(sc_balance, indent=4, sort_keys=True)))
        boxes_balances = sc_node.wallet_allBoxes()["result"]
        print("\nSC wallet boxes: {}".format(
            json.dumps(boxes_balances, indent=4, sort_keys=True)))

        self.pause()
    def run_test(self):
        mc_node = self.nodes[0]
        mc_node.generate(200)


        # Generate Tx with version -4 with no SC related outputs
        mc_address = mc_node.getnewaddress()
        tx_id = mc_node.sendtoaddress(mc_address, 10)
        tx_hex = mc_node.getrawtransaction(tx_id)

        print("MC Transaction with version -4 without SC data: \nHash = {0}\nSize = {1}\nHex = {2}\n"
              .format(str(tx_id), len(tx_hex)/2, str(tx_hex)))


        # Generate Tx with version -4 with single SidechainCreation output
        # Use the same amount and withdrawal epoch length as for unit test
        creation_amount = 50
        withdrawal_epoch_length = 1000

        sc_creation_info = SCCreationInfo(mc_node, creation_amount, withdrawal_epoch_length)
        boot_info = create_sidechain(sc_creation_info)

        sidechain_id = boot_info.sidechain_id
        sc_creation_tx_id = mc_node.getblock(mc_node.getbestblockhash())["tx"][-1]
        sc_creation_tx_hex = mc_node.getrawtransaction(sc_creation_tx_id)

        print("MC Transaction with version -4 with single SidechainCreation output: \nHash = {0}\nSize = {1}\nHex = {2}"
              "\nsidechain_id = {3}\ncreation_amount = {4}, withdrawal_epoch_length = {5}\n"
              .format(str(sc_creation_tx_id), len(sc_creation_tx_hex) / 2, str(sc_creation_tx_hex),
                      sidechain_id, creation_amount, withdrawal_epoch_length))


        # Generate Tx with version -4 with single ForwardTransfer output
        forward_transfer_amount = 10
        ft_tx_id = mc_node.sc_send(boot_info.genesis_account.publicKey, forward_transfer_amount, sidechain_id)
        ft_tx_hex = mc_node.getrawtransaction(ft_tx_id)
        print("MC Transaction with version -4 with single ForwardTransfer output: \nHash = {0}\nSize = {1}\nHex = {2}"
              "\nsidechain_id = {3}\nforward_transfer_amount = {4}, public_key = {5}\n"
              .format(str(ft_tx_id), len(ft_tx_hex) / 2, str(ft_tx_hex),
                      sidechain_id, forward_transfer_amount, boot_info.genesis_account.publicKey))


        # Generate Tx with version -4 with multiple ForwardTransfer outputs
        send_many_params = [
            {
                "scid": sidechain_id,
                "amount": 10,
                "address": "000000000000000000000000000000000000000000000000000000000000add1"
            },
            {
                "scid": sidechain_id,
                "amount": 11,
                "address": "000000000000000000000000000000000000000000000000000000000000add2"
            },
            {
                "scid": sidechain_id,
                "amount": 12,
                "address": "000000000000000000000000000000000000000000000000000000000000add3"
            }
        ]
        multiple_ft_tx_id = mc_node.sc_sendmany(send_many_params)
        multiple_ft_tx_hex = mc_node.getrawtransaction(multiple_ft_tx_id)
        print("MC Transaction with version -4 with multiple ForwardTransfer outputs: \nHash = {0}\nSize = {1}\n"
              "Hex = {2}\nForward Transfers: = {3}\n"
              .format(str(multiple_ft_tx_id), len(multiple_ft_tx_hex) / 2, str(multiple_ft_tx_hex),
                      json.dumps(send_many_params, indent=4)))