Пример #1
0
    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)
Пример #2
0
 def sc_setup_chain(self):
     mc_node_1 = self.nodes[0]
     mc_node_2 = self.nodes[1]
     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_2.hostname, websocket_port_by_mc_node_index(1))))
     network = SCNetworkConfiguration(SCCreationInfo(mc_node_1, 600, 1000),
                                      sc_node_1_configuration,
                                      sc_node_2_configuration)
     self.sc_nodes_bootstrap_info = bootstrap_sidechain_nodes(
         self.options.tmpdir, network)
Пример #3
0
def initialize_sc_datadir(dirname, n, bootstrap_info=SCBootstrapInfo, sc_node_config=SCNodeConfiguration()):

    apiAddress = "127.0.0.1"
    configsData = []
    apiPort = sc_rpc_port(n)
    bindPort = sc_p2p_port(n)
    datadir = os.path.join(dirname, "sc_node" + str(n))
    mc0datadir = os.path.join(dirname, "node0")
    websocket_config = sc_node_config.mc_connection_info
    if not os.path.isdir(datadir):
        os.makedirs(datadir)

    customFileName = './resources/template_' + str(n+1) + '.conf'
    fileToOpen = './resources/template.conf'
    if os.path.isfile(customFileName):
        fileToOpen = customFileName

    with open(fileToOpen, 'r') as templateFile:
        tmpConfig = templateFile.read()

    genesis_secrets = []
    if bootstrap_info.genesis_vrf_account is not None:
        genesis_secrets.append(bootstrap_info.genesis_vrf_account.secret)

    if bootstrap_info.genesis_account is not None:
        genesis_secrets.append(bootstrap_info.genesis_account.secret)

    config = tmpConfig % {
        'NODE_NUMBER': n,
        'DIRECTORY': dirname,
        'WALLET_SEED': "sidechain_seed_{0}".format(n),
        'API_ADDRESS': "127.0.0.1",
        'API_PORT': str(apiPort),
        'BIND_PORT': str(bindPort),
        'OFFLINE_GENERATION': "false",
        'GENESIS_SECRETS': json.dumps(genesis_secrets),
        'SIDECHAIN_ID': bootstrap_info.sidechain_id,
        'GENESIS_DATA': bootstrap_info.sidechain_genesis_block_hex,
        'POW_DATA': bootstrap_info.pow_data,
        'BLOCK_HEIGHT': bootstrap_info.mainchain_block_height,
        'NETWORK': bootstrap_info.network,
        'WITHDRAWAL_EPOCH_LENGTH': bootstrap_info.withdrawal_epoch_length,
        'WEBSOCKET_ADDRESS': websocket_config.address,
        'CONNECTION_TIMEOUT': websocket_config.connectionTimeout,
        'RECONNECTION_DELAY': websocket_config.reconnectionDelay,
        'RECONNECTION_MAX_ATTEMPS': websocket_config.reconnectionMaxAttempts,
        "THRESHOLD" : bootstrap_info.certificate_proof_info.threshold,
        "SUBMITTER_CERTIFICATE" : ("true" if sc_node_config.cert_submitter_enabled else "false"),
        "SIGNER_PUBLIC_KEY": json.dumps(bootstrap_info.certificate_proof_info.schnorr_public_keys),
        "SIGNER_PRIVATE_KEY": json.dumps(bootstrap_info.certificate_proof_info.schnorr_secrets)
    }

    configsData.append({
        "name": "node" + str(n),
        "url": "http://" + apiAddress + ":" + str(apiPort)
    })
    with open(os.path.join(datadir, "node" + str(n) + ".conf"), 'w+') as configFile:
        configFile.write(config)

    return configsData
    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)
Пример #5
0
 def sc_setup_chain(self):
     mc_node = self.nodes[0]
     sc_node_configuration = SCNodeConfiguration(
         MCConnectionInfo(address="ws://{0}:{1}".format(mc_node.hostname, websocket_port_by_mc_node_index(0)))
     )
     network = SCNetworkConfiguration(SCCreationInfo(mc_node, 100, self.sc_withdrawal_epoch_length), sc_node_configuration)
     self.sc_nodes_bootstrap_info = bootstrap_sidechain_nodes(self.options.tmpdir, network)
Пример #6
0
def initialize_sc_chain_clean(test_dir, num_nodes, genesis_secrets, genesis_info, array_of_MCConnectionInfo=[]):
    """
    Create an empty blockchain and num_nodes wallets.
    Useful if a test case wants complete control over initialization.
    """
    for i in range(num_nodes):
        sc_node_config = SCNodeConfiguration(get_websocket_configuration(i, array_of_MCConnectionInfo))
        initialize_sc_datadir(test_dir, i, genesis_secrets[i], genesis_info[i], sc_node_config)
Пример #7
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()