示例#1
0
    def run_test(self):

        mark_logs("Node 2 generates 150 block", self.nodes, DEBUG_MODE)
        self.nodes[2].generate(150)
        self.sync_all()

        # check block versions ( skip genesis that is 4)
        mark_logs(("Check that block version is %d" % BLOCK_VERSION),
                  self.nodes, DEBUG_MODE)
        for i in range(1, 151):
            v = self.nodes[0].getblock(str(i))['version']
            assert_equal(v, BLOCK_VERSION)

        # Mine 51 up-version blocks, they are supported up to sidechain fork
        mark_logs("Node 1 generates 51 block with an up-version", self.nodes,
                  DEBUG_MODE)
        self.nodes[1].generate(51)
        self.sync_all()

        # check block versions
        mark_logs(("Check that block version is %d" % UP_VERSION), self.nodes,
                  DEBUG_MODE)
        for i in range(151, 201):
            v = self.nodes[0].getblock(str(i))['version']
            assert_equal(v, UP_VERSION)

        try:
            self.nodes[0].generate(1)
            raise AssertionError("Can not generate blocks with version = 2")
        except JSONRPCException, e:
            errorString = e.error['message']
            mark_logs(
                errorString +
                " ===> Ok, Can not generate blocks with version = 2",
                self.nodes, DEBUG_MODE)
示例#2
0
def template_to_bytes(tmpl, txlist, certlist, input_sc_commitment=None):
    blkver = pack('<L', tmpl['version'])
    objlist = txlist + certlist
    mrklroot = genmrklroot(list(dblsha(a) for a in objlist))
    sc_commitment = b'\0' * 32
    if input_sc_commitment != None:
        sc_commitment = input_sc_commitment
        mark_logs(("sc_commitment set in block template: %s" %
                   swap_bytes(binascii.hexlify(sc_commitment))), NODE_LIST,
                  DEBUG_MODE)
    timestamp = pack('<L', tmpl['curtime'])
    nonce = b'\0' * 32
    soln = b'\0'
    blk = blkver + a2b_hex(
        tmpl['previousblockhash']
    )[::-1] + mrklroot + sc_commitment + timestamp + a2b_hex(
        tmpl['bits'])[::-1] + nonce + soln
    blk += varlenEncode(len(txlist))
    for tx in txlist:
        blk += tx
    if tmpl['version'] == SC_CERTIFICATE_BLOCK_VERSION:
        # fill vector of certificates from this version on
        blk += varlenEncode(len(certlist))
        for cert in certlist:
            blk += cert
    return blk
示例#3
0
 def refresh_sidechain(self, sc_info, scid, nIdx=0):
     mark_logs("Node{} generating 1 block".format(nIdx), self.nodes,
               DEBUG_MODE)
     self.nodes[nIdx].generate(1)
     self.sync_all()
     sc_info.append(self.nodes[nIdx].getscinfo(scid)['items'][0])
     mark_logs("  ==> height {}".format(self.nodes[nIdx].getblockcount()),
               self.nodes, DEBUG_MODE)
示例#4
0
 def send_unconf_to_node1(self, taddr, quota, numbtx):
     tot_amount = 0
     for i in range(1, numbtx+1):
         amount = i*quota
         tot_amount += amount
         tx = self.nodes[1].sendtoaddress(taddr, amount)
         mark_logs("Node 1 sent {} coins to Node0 address {} via tx {}.".format(amount, taddr, tx), self.nodes, DEBUG_MODE)
     return tot_amount
示例#5
0
 def create_sc(cmdInput, node):
     try:
         res = node.sc_create(cmdInput)
         tx = res['txid']
         scid = res['scid']
     except JSONRPCException, e:
         errorString = e.error['message']
         mark_logs(errorString, self.nodes, DEBUG_MODE)
         assert_true(False)
示例#6
0
 def getEpochData(self, sc_creating_height):
     current_height = self.nodes[0].getblockcount()
     epoch_number = (current_height - sc_creating_height +
                     1) // EPOCH_LENGTH - 1
     mark_logs(
         "Current height {}, Sc creation height {}, epoch length {} --> current epoch number {}"
         .format(current_height, sc_creating_height, EPOCH_LENGTH,
                 epoch_number), self.nodes, DEBUG_MODE)
     epoch_block_hash = self.nodes[0].getblockhash(sc_creating_height - 1 +
                                                   ((epoch_number + 1) *
                                                    EPOCH_LENGTH))
     return epoch_block_hash, epoch_number
示例#7
0
    def run_test(self):
        ''' This test validates the rpc cmds for SBH wallet
        '''
        amount_1 = Decimal("40.0")
        sc_creation_amount = Decimal("20.0")
        sc_fwd_amount = Decimal("15.0")
        bwt_amount1 = Decimal("10.0")
        amount_2 = Decimal("3.0")

        txs_node1 = []

        # network topology: (0)--(1)--(2)
        mark_logs("\nNode 0 generates 220 blocks", self.nodes, DEBUG_MODE)
        self.nodes[0].generate(220)
        self.sync_all()

        taddr_1 = self.nodes[1].getnewaddress()
        #----------------------------------------------------------------------------------------------
        tx = self.nodes[0].sendtoaddress(taddr_1, amount_1)
        self.sync_all()
        txs_node1.append(tx)
        mark_logs(
            "\n===> Node0 sent {} coins to Node1 at addr {}".format(
                amount_1, taddr_1), self.nodes, DEBUG_MODE)

        mark_logs("\nNode0 generates 1 more block", self.nodes, DEBUG_MODE)
        self.nodes[0].generate(1)
        self.sync_all()

        #generate wCertVk and constant
        mcTest = MCTestUtils(self.options.tmpdir, self.options.srcdir)
        vk = mcTest.generate_params("sc1")
        constant = generate_random_field_element_hex()

        sc_creating_height = self.nodes[0].getblockcount() + 1
        sc_toaddress = "5c1dadd"
        minconf = 1
        fee = Decimal("0.000025")
        cmdInput = {
            "withdrawalEpochLength": EPOCH_LENGTH,
            "fromaddress": taddr_1,
            "toaddress": sc_toaddress,
            "amount": sc_creation_amount,
            "changeaddress": taddr_1,
            "fee": fee,
            "wCertVk": vk,
            "constant": constant
        }

        try:
            #----------------------------------------------------------------------------------------------
            res = self.nodes[1].create_sidechain(cmdInput)
            tx = res['txid']
            scid = res['scid']
            txs_node1.append(tx)
        except JSONRPCException, e:
            errorString = e.error['message']
            mark_logs(errorString, self.nodes, DEBUG_MODE)
            assert_true(False)
示例#8
0
    def run_test(self):
        '''
        Create a few SCs specifying related configurations for the custom fields that a cert must set; during
        this phase, different versions of cmd for SC creation are tested.
        Send some certificate with custom fields configured accordingly to the SC they refer.
        Along the test execution, some negative test is also performed.
        JSON representation of scinfo as well as tx/cert are checked for expected contents too.
        '''

        # network topology: (0)--(1)

        # Read the huge bit vector from file
        with open(
                os.path.dirname(os.path.abspath(__file__)) +
                "/../zen/test_data/16_GB_bitvector.bz2", "rb") as f:
            BIT_VECTOR_BUF_HUGE = binascii.hexlify(f.read())

        mark_logs("Node 1 generates 2 block", self.nodes, DEBUG_MODE)
        self.nodes[1].generate(2)
        self.sync_all()

        mark_logs("Node 0 generates {} block".format(MINIMAL_SC_HEIGHT),
                  self.nodes, DEBUG_MODE)
        self.nodes[0].generate(MINIMAL_SC_HEIGHT)
        self.sync_all()

        #generate wCertVk and constant
        mcTest = CertTestUtils(self.options.tmpdir, self.options.srcdir)
        vk = mcTest.generate_params('sc1')
        constant1 = generate_random_field_element_hex()

        amount = Decimal("1.0")
        fee = 0.000025

        #-------------------------------------------------------
        bad_obj = {"a": 1, "b": 2}
        cmdInput = {
            'version': 0,
            'withdrawalEpochLength': EPOCH_LENGTH,
            'vFieldElementCertificateFieldConfig': bad_obj,
            'toaddress': "abcd",
            'amount': amount,
            'fee': fee,
            'wCertVk': vk
        }

        mark_logs(
            "\nNode 1 create SC with wrong vFieldElementCertificateFieldConfig obj in input (expecting failure...)",
            self.nodes, DEBUG_MODE)
        try:
            self.nodes[1].sc_create(cmdInput)
            assert_true(False)
        except JSONRPCException, e:
            errorString = e.error['message']
            mark_logs(errorString, self.nodes, DEBUG_MODE)
            assert_true("not an array" in errorString)
示例#9
0
    def run_test(self):
        '''
        This test try creating a SC with sc_create using invalid parameters and valid parameters.
        It also checks the coin mature time of the FT
        '''
        # network topology: (0)--(1)--(2)

        mark_logs("Node 1 generates 220 block", self.nodes, DEBUG_MODE)
        self.nodes[1].generate(220)
        self.sync_all()

        creation_amount = Decimal("1.0")
        fwt_amount_1 = Decimal("2.0")
        fwt_amount_2 = Decimal("2.0")
        fwt_amount_3 = Decimal("3.0")
        fwt_amount_many = fwt_amount_1 + fwt_amount_2 + fwt_amount_3

        #generate wCertVk and constant
        mcTest = MCTestUtils(self.options.tmpdir, self.options.srcdir)
        vk = mcTest.generate_params("sc1")
        constant = generate_random_field_element_hex()

        # ---------------------------------------------------------------------------------------
        # Node 2 try creating a SC with insufficient funds
        mark_logs("\nNode 2 try creating a SC with insufficient funds", self.nodes, DEBUG_MODE)

        amounts = [{"address": "dada", "amount": creation_amount}]
        errorString = ""
        try:
            self.nodes[2].sc_create(123, "dada", creation_amount, vk, "", constant)
        except JSONRPCException, e:
            errorString = e.error['message']
            mark_logs(errorString, self.nodes, DEBUG_MODE)
示例#10
0
    def run_test(self):
        NODE_LIST = self.nodes

        self.nodes[0].generate(
            1)  # Mine a block to leave initial block download
        self.sync_all()

        mark_logs(("active chain height = %d: testing before sidechain fork" %
                   self.nodes[0].getblockcount()), self.nodes, DEBUG_MODE)
        self.doTest()

        # reach the fork where certificates are supported
        self.nodes[0].generate(20)
        self.sync_all()

        mark_logs(("active chain height = %d: testing after sidechain fork" %
                   self.nodes[0].getblockcount()), self.nodes, DEBUG_MODE)

        # create a sidechain and a certificate for it in the mempool
        mcTest = MCTestUtils(self.options.tmpdir, self.options.srcdir)
        vk = mcTest.generate_params("sc1")
        constant = generate_random_field_element_hex()

        creating_tx = self.nodes[1].sc_create(SC_EPOCH_LENGTH, "dada",
                                              SC_CREATION_AMOUNT, vk,
                                              "bb" * 1024, constant)
        self.sync_all()

        decoded_tx = self.nodes[1].getrawtransaction(creating_tx, 1)
        scid = decoded_tx['vsc_ccout'][0]['scid']
        mark_logs("created SC id: {}".format(scid), self.nodes, DEBUG_MODE)

        current_height = self.nodes[1].getblockcount()
        pebh = self.nodes[1].getblockhash(current_height)
        block_list = self.nodes[0].generate(SC_EPOCH_LENGTH)
        self.sync_all()

        pkh = self.nodes[0].getnewaddress("", True)
        amounts = [{"pubkeyhash": pkh, "amount": SC_CERT_AMOUNT}]

        #create wCert proof
        eph = block_list[-1]
        proof = mcTest.create_test_proof("sc1", 0, eph, pebh, 0, constant,
                                         [pkh], [SC_CERT_AMOUNT])

        fee = 0.000023
        cert = self.nodes[0].send_certificate(scid, 0, 0, block_list[-1],
                                              proof, amounts, fee)
        self.sync_all()
        assert_true(cert in self.nodes[0].getrawmempool())

        # just one more tx, for having 3 generic txobjs and testing malleability of cert (Test 4)
        tx = self.nodes[0].sendtoaddress(self.nodes[0].getnewaddress(), 0.01)
        self.sync_all()
        assert_true(tx in self.nodes[0].getrawmempool())

        self.doTest()

        self.nodes[0].generate(1)
        self.sync_all()
示例#11
0
        def flood_mempool():
            mark_logs("Creating many txes...", self.nodes, DEBUG_MODE)
            tot_num_tx = 0
            tot_tx_sz = 0
            taddr_node1 = self.nodes[0].getnewaddress()

            fee = Decimal('0.001')

            # there are a few coinbase utxo now matured
            listunspent = self.nodes[0].listunspent()
            print "num of utxo: ", len(listunspent)

            while True:
                if len(listunspent) <= tot_num_tx:
                    # all utxo have been spent
                    self.sync_all()
                    break

                utxo = listunspent[tot_num_tx]
                change = utxo['amount'] - Decimal(fee)
                raw_inputs  = [ {'txid' : utxo['txid'], 'vout' : utxo['vout']}]
                raw_outs    = { taddr_node1: change }
                try:
                    raw_tx = self.nodes[0].createrawtransaction(raw_inputs, raw_outs)
                    signed_tx = self.nodes[0].signrawtransaction(raw_tx)
                    tx = self.nodes[0].sendrawtransaction(signed_tx['hex'])
                except JSONRPCException, e:
                    errorString = e.error['message']
                    print "Send raw tx failed with reason {}".format(errorString)
                    assert(False)

                tot_num_tx += 1
                hexTx = self.nodes[0].getrawtransaction(tx)
                sz = len(hexTx)//2
                tot_tx_sz += sz

                if tot_tx_sz > 5*EPOCH_LENGTH*BLK_MAX_SZ:
                    self.sync_all()
                    break
示例#12
0
    def run_test(self):
        '''
        This test try to create a SC using the command sc_create using invalid parameters and valid parameters.
        '''
        #{"withdrawalEpochLength", "fromaddress", "toaddress", "amount", "minconf", "fee", "customData"};

        # network topology: (0)--(1)

        mark_logs("Node 1 generates 2 block", self.nodes, DEBUG_MODE)
        self.nodes[1].generate(2)
        self.sync_all()

        mark_logs("Node 0 generates {} block".format(MINIMAL_SC_HEIGHT),
                  self.nodes, DEBUG_MODE)
        self.nodes[0].generate(MINIMAL_SC_HEIGHT)
        self.sync_all()

        tx = []
        errorString = ""
        toaddress = "abcdef"

        #generate wCertVk and constant
        mcTest = CertTestUtils(self.options.tmpdir, self.options.srcdir)
        vk = mcTest.generate_params('sc1')
        constant = generate_random_field_element_hex()

        # create with wrong key in input
        #------------------------------------
        amount = 12.0
        fee = 0.000025

        cmdInput = {
            'version': 0,
            'wrong_key': 123,
            'toaddress': toaddress,
            'amount': amount,
            'fee': fee,
            'wCertVk': vk
        }

        mark_logs("\nNode 1 create SC with wrong key in input", self.nodes,
                  DEBUG_MODE)
        try:
            self.nodes[1].sc_create(cmdInput)
            assert_true(False)
        except JSONRPCException, e:
            errorString = e.error['message']
            mark_logs(errorString, self.nodes, DEBUG_MODE)
            assert_true("wrong_key" in errorString)
示例#13
0
        def advance_sidechains_epoch(num_of_scs):

            for i in range(0, num_of_scs):

                if i == 0:
                    self.nodes[0].generate(EPOCH_LENGTH)
                    self.sync_all()
                    # these parameters are valid for all scs since they share the same epoch length
                    epoch_number, epoch_cum_tree_hash = get_epoch_data(
                        scids[i], self.nodes[0], EPOCH_LENGTH)

                print "Generating cert proof..."
                t0 = time.time()
                scid_swapped = str(swap_bytes(scids[i]))

                proof = certMcTest.create_test_proof(
                    "scs", scid_swapped, epoch_number, q, MBTR_SC_FEE,
                    FT_SC_FEE, epoch_cum_tree_hash, constant, [], [],
                    proofCfeArray, CERT_NUM_CONSTRAINTS, SEGMENT_SIZE)
                assert_true(proof != None)
                t1 = time.time()
                print "...proof generated: {} secs".format(t1 - t0)

                try:
                    cert = self.nodes[0].sc_send_certificate(
                        scids[i], epoch_number, q, epoch_cum_tree_hash, proof,
                        [], FT_SC_FEE, MBTR_SC_FEE, CERT_FEE, "", vCfe, vCmt)
                except JSONRPCException, e:
                    errorString = e.error['message']
                    print "Send certificate failed with reason {}".format(
                        errorString)
                    assert (False)
                self.sync_all()

                mark_logs(
                    "==> certificate for SC{} epoch {} {} (chain height={})".
                    format(i, epoch_number, cert,
                           self.nodes[0].getblockcount()), self.nodes,
                    DEBUG_MODE)
示例#14
0
    def run_test(self):
        '''
        The test creates a sc, send funds to it and then sends a certificate to it,
        Then test that getrawtransaction decodes correctly tx and cert when possible. 
        '''

        # forward transfer amounts
        creation_amount = Decimal("0.5")
        fwt_amount = Decimal("50")
        bwt_amount = Decimal("50")

        # node 1 earns some coins, they would be available after 100 blocks
        mark_logs("Node 1 generates 1 block", self.nodes, DEBUG_MODE)
        self.nodes[1].generate(1)
        self.sync_all()

        mark_logs("Node 0 generates {} block".format(MINIMAL_SC_HEIGHT),
                  self.nodes, DEBUG_MODE)
        self.nodes[0].generate(MINIMAL_SC_HEIGHT)
        self.sync_all()

        # SC creation
        #generate wCertVk and constant
        mcTest = CertTestUtils(self.options.tmpdir, self.options.srcdir)
        vk_tag = "sc1"
        vk = mcTest.generate_params(vk_tag)
        constant = generate_random_field_element_hex()
        cmdInput = {
            "version": 0,
            "withdrawalEpochLength": EPOCH_LENGTH,
            "toaddress": "dada",
            "amount": creation_amount,
            "wCertVk": vk,
            "constant": constant,
        }

        ret = self.nodes[1].sc_create(cmdInput)

        creating_tx = ret['txid']
        scid = ret['scid']
        scid_swapped = str(swap_bytes(scid))
        mark_logs(
            "Node 1 created the SC spending {} coins via tx {}.".format(
                creation_amount, creating_tx), self.nodes, DEBUG_MODE)
        self.sync_all()

        decoded_tx_mempool = self.nodes[1].getrawtransaction(creating_tx, 1)
        assert_equal(scid, decoded_tx_mempool['vsc_ccout'][0]['scid'])

        decoded_tx_mempool_hex = self.nodes[1].getrawtransaction(creating_tx)
        dec = self.nodes[1].decoderawtransaction(decoded_tx_mempool_hex)
        assert_equal(creating_tx, dec['txid'])
        assert_equal(scid, dec['vsc_ccout'][0]['scid'])

        mark_logs("Node0 confirms Sc creation generating 1 block", self.nodes,
                  DEBUG_MODE)
        self.nodes[0].generate(1)
        sc_creating_height = self.nodes[0].getblockcount()
        self.sync_all()

        decoded_tx_notxindex = self.nodes[1].getrawtransaction(creating_tx, 1)
        assert_equal(decoded_tx_mempool['hex'], decoded_tx_notxindex['hex'])

        decoded_tx_txindex = self.nodes[2].getrawtransaction(creating_tx, 1)
        assert_equal(decoded_tx_mempool['hex'], decoded_tx_txindex['hex'])

        # Fwd Transfer to Sc
        mark_logs("Node0 sends fwd transfer", self.nodes, DEBUG_MODE)

        mc_return_address = self.nodes[0].getnewaddress()
        cmdInput = [{
            'toaddress': "abcd",
            'amount': fwt_amount,
            "scid": scid,
            'mcReturnAddress': mc_return_address
        }]
        fwd_tx = self.nodes[0].sc_send(cmdInput)

        self.sync_all()

        decoded_tx_mempool = self.nodes[1].getrawtransaction(fwd_tx, 1)
        assert_equal(scid, decoded_tx_mempool['vft_ccout'][0]['scid'])

        mark_logs("Node0 confirms fwd transfer generating 1 block", self.nodes,
                  DEBUG_MODE)
        self.nodes[0].generate(1)
        self.sync_all()

        decoded_tx_notxindex = self.nodes[1].getrawtransaction(fwd_tx, 1)
        assert_equal(decoded_tx_mempool['hex'], decoded_tx_notxindex['hex'])
        decoded_tx_txindex = self.nodes[2].getrawtransaction(fwd_tx, 1)
        assert_equal(decoded_tx_mempool['hex'], decoded_tx_txindex['hex'])

        mark_logs(
            "Node0 generating 3 more blocks to achieve end of withdrawal epoch",
            self.nodes, DEBUG_MODE)
        self.nodes[0].generate(3)
        self.sync_all()

        epoch_number, epoch_cum_tree_hash = get_epoch_data(
            scid, self.nodes[0], EPOCH_LENGTH)

        addr_node1 = self.nodes[1].getnewaddress()
        amount_cert_1 = [{"address": addr_node1, "amount": bwt_amount}]

        #Create proof for WCert
        quality = 0
        proof = mcTest.create_test_proof(vk_tag, scid_swapped, epoch_number,
                                         quality, MBTR_SC_FEE, FT_SC_FEE,
                                         epoch_cum_tree_hash, constant,
                                         [addr_node1], [bwt_amount])

        mark_logs(
            "Node 0 performs a bwd transfer of {} coins to Node1 address {}".
            format(amount_cert_1[0]["address"],
                   amount_cert_1[0]["amount"]), self.nodes, DEBUG_MODE)
        try:
            cert_epoch_0 = self.nodes[0].sc_send_certificate(
                scid, epoch_number, quality, epoch_cum_tree_hash, proof,
                amount_cert_1, FT_SC_FEE, MBTR_SC_FEE, CERT_FEE)
            mark_logs("Certificate is {}".format(cert_epoch_0), self.nodes,
                      DEBUG_MODE)
        except JSONRPCException, e:
            errorString = e.error['message']
            mark_logs(
                "Send certificate failed with reason {}".format(errorString),
                self.nodes, DEBUG_MODE)
            assert (False)
示例#15
0
            errorString = e.error['message']
            mark_logs(errorString, self.nodes, DEBUG_MODE)
            assert_true("amount" in errorString)

        # create with a missing mandatory key in input
        #------------------------------------------------
        cmdInput = {
            'version': 0,
            'withdrawalEpochLength': 10,
            'toaddress': toaddress,
            'fee': fee,
            'wCertVk': vk,
            'customData': "bb" * 1024
        }

        mark_logs("\nNode 1 create SC with duplicate key in input", self.nodes,
                  DEBUG_MODE)
        try:
            self.nodes[1].sc_create(cmdInput)
            assert_true(False)
        except JSONRPCException, e:
            errorString = e.error['message']
            mark_logs(errorString, self.nodes, DEBUG_MODE)
            assert_true("amount" in errorString)

        # create with a bad value for amount
        #------------------------------------------------
        cmdInput = {
            'version': 0,
            'withdrawalEpochLength': 10,
            'toaddress': toaddress,
            'amount': -0.1,
示例#16
0
        try:
            cert_epoch_1 = self.nodes[0].sc_send_certificate(
                scid, epoch_number, quality, epoch_cum_tree_hash, proof, [],
                FT_SC_FEE, MBTR_SC_FEE, nullFee)
            mark_logs("Certificate is {}".format(cert_epoch_1), self.nodes,
                      DEBUG_MODE)
            self.sync_all()
        except JSONRPCException, e:
            errorString = e.error['message']
            mark_logs(
                "Send certificate failed with reason {}".format(errorString),
                self.nodes, DEBUG_MODE)
            assert (False)

        mark_logs(
            "Check the certificate for this scid has no vin and no vouts",
            self.nodes, DEBUG_MODE)
        decoded_cert_mempool = self.nodes[0].getrawtransaction(cert_epoch_1, 1)
        assert_equal(decoded_cert_mempool['cert']['scid'], scid)

        mark_logs("Node0 confims bwd transfer generating 1 block", self.nodes,
                  DEBUG_MODE)
        self.nodes[0].generate(1)
        self.sync_all()

        # no more in mempool, only node with txindex=1 can decode it
        try:
            decoded_cert_notxindex = self.nodes[1].getrawtransaction(
                cert_epoch_1, 1)
        except JSONRPCException, e:
            errorString = e.error['message']
示例#17
0
class sc_cert_getraw(BitcoinTestFramework):

    alert_filename = None

    def setup_chain(self, split=False):
        print("Initializing test directory " + self.options.tmpdir)
        initialize_chain_clean(self.options.tmpdir, NUMB_OF_NODES)
        self.alert_filename = os.path.join(self.options.tmpdir, "alert.txt")
        with open(self.alert_filename, 'w'):
            pass  # Just open then close to create zero-length file

    def setup_network(self, split=False):
        self.nodes = []

        self.nodes = start_nodes(
            NUMB_OF_NODES,
            self.options.tmpdir,
            extra_args=[[
                '-debug=py', '-debug=sc', '-debug=mempool', '-debug=net',
                '-debug=cert', '-debug=zendoo_mc_cryptolib',
                '-scproofqueuesize=0', '-logtimemicros=1'
            ],
                        [
                            '-debug=py', '-debug=sc', '-debug=mempool',
                            '-debug=net', '-debug=cert',
                            '-debug=zendoo_mc_cryptolib',
                            '-scproofqueuesize=0', '-logtimemicros=1'
                        ],
                        [
                            '-txindex=1', '-debug=py', '-debug=sc',
                            '-debug=mempool', '-debug=net', '-debug=cert',
                            '-debug=zendoo_mc_cryptolib',
                            '-scproofqueuesize=0', '-logtimemicros=1'
                        ]])

        connect_nodes_bi(self.nodes, 0, 1)
        connect_nodes_bi(self.nodes, 1, 2)
        sync_blocks(self.nodes[1:NUMB_OF_NODES])
        sync_mempools(self.nodes[1:NUMB_OF_NODES])
        self.is_network_split = split
        self.sync_all()

    def run_test(self):
        '''
        The test creates a sc, send funds to it and then sends a certificate to it,
        Then test that getrawtransaction decodes correctly tx and cert when possible. 
        '''

        # forward transfer amounts
        creation_amount = Decimal("0.5")
        fwt_amount = Decimal("50")
        bwt_amount = Decimal("50")

        # node 1 earns some coins, they would be available after 100 blocks
        mark_logs("Node 1 generates 1 block", self.nodes, DEBUG_MODE)
        self.nodes[1].generate(1)
        self.sync_all()

        mark_logs("Node 0 generates {} block".format(MINIMAL_SC_HEIGHT),
                  self.nodes, DEBUG_MODE)
        self.nodes[0].generate(MINIMAL_SC_HEIGHT)
        self.sync_all()

        # SC creation
        #generate wCertVk and constant
        mcTest = CertTestUtils(self.options.tmpdir, self.options.srcdir)
        vk_tag = "sc1"
        vk = mcTest.generate_params(vk_tag)
        constant = generate_random_field_element_hex()
        cmdInput = {
            "version": 0,
            "withdrawalEpochLength": EPOCH_LENGTH,
            "toaddress": "dada",
            "amount": creation_amount,
            "wCertVk": vk,
            "constant": constant,
        }

        ret = self.nodes[1].sc_create(cmdInput)

        creating_tx = ret['txid']
        scid = ret['scid']
        scid_swapped = str(swap_bytes(scid))
        mark_logs(
            "Node 1 created the SC spending {} coins via tx {}.".format(
                creation_amount, creating_tx), self.nodes, DEBUG_MODE)
        self.sync_all()

        decoded_tx_mempool = self.nodes[1].getrawtransaction(creating_tx, 1)
        assert_equal(scid, decoded_tx_mempool['vsc_ccout'][0]['scid'])

        decoded_tx_mempool_hex = self.nodes[1].getrawtransaction(creating_tx)
        dec = self.nodes[1].decoderawtransaction(decoded_tx_mempool_hex)
        assert_equal(creating_tx, dec['txid'])
        assert_equal(scid, dec['vsc_ccout'][0]['scid'])

        mark_logs("Node0 confirms Sc creation generating 1 block", self.nodes,
                  DEBUG_MODE)
        self.nodes[0].generate(1)
        sc_creating_height = self.nodes[0].getblockcount()
        self.sync_all()

        decoded_tx_notxindex = self.nodes[1].getrawtransaction(creating_tx, 1)
        assert_equal(decoded_tx_mempool['hex'], decoded_tx_notxindex['hex'])

        decoded_tx_txindex = self.nodes[2].getrawtransaction(creating_tx, 1)
        assert_equal(decoded_tx_mempool['hex'], decoded_tx_txindex['hex'])

        # Fwd Transfer to Sc
        mark_logs("Node0 sends fwd transfer", self.nodes, DEBUG_MODE)

        mc_return_address = self.nodes[0].getnewaddress()
        cmdInput = [{
            'toaddress': "abcd",
            'amount': fwt_amount,
            "scid": scid,
            'mcReturnAddress': mc_return_address
        }]
        fwd_tx = self.nodes[0].sc_send(cmdInput)

        self.sync_all()

        decoded_tx_mempool = self.nodes[1].getrawtransaction(fwd_tx, 1)
        assert_equal(scid, decoded_tx_mempool['vft_ccout'][0]['scid'])

        mark_logs("Node0 confirms fwd transfer generating 1 block", self.nodes,
                  DEBUG_MODE)
        self.nodes[0].generate(1)
        self.sync_all()

        decoded_tx_notxindex = self.nodes[1].getrawtransaction(fwd_tx, 1)
        assert_equal(decoded_tx_mempool['hex'], decoded_tx_notxindex['hex'])
        decoded_tx_txindex = self.nodes[2].getrawtransaction(fwd_tx, 1)
        assert_equal(decoded_tx_mempool['hex'], decoded_tx_txindex['hex'])

        mark_logs(
            "Node0 generating 3 more blocks to achieve end of withdrawal epoch",
            self.nodes, DEBUG_MODE)
        self.nodes[0].generate(3)
        self.sync_all()

        epoch_number, epoch_cum_tree_hash = get_epoch_data(
            scid, self.nodes[0], EPOCH_LENGTH)

        addr_node1 = self.nodes[1].getnewaddress()
        amount_cert_1 = [{"address": addr_node1, "amount": bwt_amount}]

        #Create proof for WCert
        quality = 0
        proof = mcTest.create_test_proof(vk_tag, scid_swapped, epoch_number,
                                         quality, MBTR_SC_FEE, FT_SC_FEE,
                                         epoch_cum_tree_hash, constant,
                                         [addr_node1], [bwt_amount])

        mark_logs(
            "Node 0 performs a bwd transfer of {} coins to Node1 address {}".
            format(amount_cert_1[0]["address"],
                   amount_cert_1[0]["amount"]), self.nodes, DEBUG_MODE)
        try:
            cert_epoch_0 = self.nodes[0].sc_send_certificate(
                scid, epoch_number, quality, epoch_cum_tree_hash, proof,
                amount_cert_1, FT_SC_FEE, MBTR_SC_FEE, CERT_FEE)
            mark_logs("Certificate is {}".format(cert_epoch_0), self.nodes,
                      DEBUG_MODE)
        except JSONRPCException, e:
            errorString = e.error['message']
            mark_logs(
                "Send certificate failed with reason {}".format(errorString),
                self.nodes, DEBUG_MODE)
            assert (False)

        self.sync_all()

        decoded_cert_mempool = self.nodes[1].getrawtransaction(cert_epoch_0, 1)
        decoded_cert_mempool2 = self.nodes[1].getrawtransaction(
            cert_epoch_0, 1)
        assert_equal(decoded_cert_mempool, decoded_cert_mempool2)
        assert_equal(scid, decoded_cert_mempool['cert']['scid'])

        decoded_cert_mempool_hex = self.nodes[1].getrawtransaction(
            cert_epoch_0)
        decoded_cert_mempool_hex2 = self.nodes[1].getrawtransaction(
            cert_epoch_0)
        assert_equal(decoded_cert_mempool_hex, decoded_cert_mempool_hex2)
        dec = self.nodes[2].decoderawtransaction(decoded_cert_mempool_hex)
        assert_equal(cert_epoch_0, dec['txid'])
        assert_equal(scid, dec['cert']['scid'])
        dec2 = self.nodes[2].decoderawtransaction(decoded_cert_mempool_hex)
        assert_equal(dec2, dec)

        mark_logs("Node0 confims bwd transfer generating 1 block", self.nodes,
                  DEBUG_MODE)
        mined = self.nodes[0].generate(1)[0]
        self.sync_all()

        decoded_cert_notxindex = self.nodes[1].getrawtransaction(
            cert_epoch_0, 1)
        assert_equal(decoded_cert_mempool['hex'],
                     decoded_cert_notxindex['hex'])
        decoded_cert_txindex = self.nodes[2].getrawtransaction(cert_epoch_0, 1)
        assert_equal(decoded_cert_mempool['hex'], decoded_cert_txindex['hex'])

        mark_logs(
            "Node0 generating enough blocks to move to new withdrawal epoch",
            self.nodes, DEBUG_MODE)
        self.nodes[0].generate(EPOCH_LENGTH - 1)
        self.sync_all()

        epoch_number, epoch_cum_tree_hash = get_epoch_data(
            scid, self.nodes[0], EPOCH_LENGTH)

        mark_logs(
            "Generate new certificate for epoch {}. No bwt and no fee are included"
            .format(epoch_number), self.nodes, DEBUG_MODE)

        # Create new proof for WCert
        quality = 1
        proof = mcTest.create_test_proof(vk_tag, scid_swapped, epoch_number,
                                         quality, MBTR_SC_FEE, FT_SC_FEE,
                                         epoch_cum_tree_hash, constant, [], [])

        nullFee = Decimal("0.0")
        try:
            cert_epoch_1 = self.nodes[0].sc_send_certificate(
                scid, epoch_number, quality, epoch_cum_tree_hash, proof, [],
                FT_SC_FEE, MBTR_SC_FEE, nullFee)
            mark_logs("Certificate is {}".format(cert_epoch_1), self.nodes,
                      DEBUG_MODE)
            self.sync_all()
        except JSONRPCException, e:
            errorString = e.error['message']
            mark_logs(
                "Send certificate failed with reason {}".format(errorString),
                self.nodes, DEBUG_MODE)
            assert (False)
示例#18
0
class sc_cert_base(BitcoinTestFramework):

    alert_filename = None

    def setup_chain(self, split=False):
        print("Initializing test directory " + self.options.tmpdir)
        initialize_chain_clean(self.options.tmpdir, NUMB_OF_NODES)
        self.alert_filename = os.path.join(self.options.tmpdir, "alert.txt")
        with open(self.alert_filename, 'w'):
            pass  # Just open then close to create zero-length file

    def setup_network(self, split=False):
        self.nodes = []

        self.nodes = start_nodes(
            NUMB_OF_NODES,
            self.options.tmpdir,
            extra_args=[[
                '-debug=py', '-debug=sc', '-debug=mempool', '-debug=net',
                '-debug=cert', '-debug=zendoo_mc_cryptolib', '-logtimemicros=1'
            ]] * NUMB_OF_NODES)

        connect_nodes_bi(self.nodes, 0, 1)
        connect_nodes_bi(self.nodes, 1, 2)
        sync_blocks(self.nodes[1:NUMB_OF_NODES])
        sync_mempools(self.nodes[1:NUMB_OF_NODES])
        self.is_network_split = split
        self.sync_all()

    def run_test(self):

        # forward transfer amounts
        creation_amount = Decimal("0.5")
        fwt_amount = Decimal("50")
        bwt_amount_bad = Decimal("100.0")
        bwt_amount = Decimal("50")

        self.nodes[0].getblockhash(0)

        # node 1 earns some coins, they would be available after 100 blocks
        mark_logs("Node 1 generates 1 block", self.nodes, DEBUG_MODE)
        self.nodes[1].generate(1)
        self.sync_all()

        mark_logs("Node 0 generates 220 block", self.nodes, DEBUG_MODE)
        self.nodes[0].generate(220)
        self.sync_all()

        # SC creation
        bal_before_sc_creation = self.nodes[1].getbalance("", 0)
        mark_logs(
            "Node1 balance before SC creation: {}".format(
                bal_before_sc_creation), self.nodes, DEBUG_MODE)

        #generate wCertVk and constant
        mcTest = MCTestUtils(self.options.tmpdir, self.options.srcdir)
        vk = mcTest.generate_params("sc1")
        constant = generate_random_field_element_hex()

        creating_tx = self.nodes[1].sc_create(EPOCH_LENGTH, "dada",
                                              creation_amount, vk, "",
                                              constant)
        mark_logs(
            "Node 1 created the SC spending {} coins via tx {}.".format(
                creation_amount, creating_tx), self.nodes, DEBUG_MODE)
        self.sync_all()

        decoded_tx = self.nodes[1].getrawtransaction(creating_tx, 1)
        scid = decoded_tx['vsc_ccout'][0]['scid']
        mark_logs("created SC id: {}".format(scid), self.nodes, DEBUG_MODE)

        mark_logs("Node0 confirms Sc creation generating 1 block", self.nodes,
                  DEBUG_MODE)
        self.nodes[0].generate(1)
        sc_creating_height = self.nodes[0].getblockcount()
        self.sync_all()

        # Check node 1 balance following sc creation
        fee_sc_creation = self.nodes[1].gettransaction(creating_tx)['fee']
        mark_logs("Fee paid for SC creation: {}".format(fee_sc_creation),
                  self.nodes, DEBUG_MODE)
        bal_after_sc_creation = self.nodes[1].getbalance("", 0)
        mark_logs(
            "Node1 balance after SC creation: {}".format(
                bal_after_sc_creation), self.nodes, DEBUG_MODE)
        assert_equal(bal_before_sc_creation,
                     bal_after_sc_creation + creation_amount - fee_sc_creation)

        assert_equal(self.nodes[0].getscinfo(scid)['balance'], Decimal(0))
        assert_equal(
            self.nodes[0].getscinfo(scid)['immature amounts'][0]['amount'],
            creation_amount)

        # Fwd Transfer to Sc
        bal_before_fwd_tx = self.nodes[0].getbalance("", 0)
        mark_logs("Node0 balance before fwd tx: {}".format(bal_before_fwd_tx),
                  self.nodes, DEBUG_MODE)
        fwd_tx = self.nodes[0].sc_send("abcd", fwt_amount, scid)
        mark_logs(
            "Node0 transfers {} coins to SC with tx {}...".format(
                fwt_amount, fwd_tx), self.nodes, DEBUG_MODE)
        self.sync_all()

        mark_logs("Node0 confirms fwd transfer generating 1 block", self.nodes,
                  DEBUG_MODE)
        self.nodes[0].generate(1)
        self.sync_all()

        # Check node 0 balance following fwd tx
        fee_fwt = self.nodes[0].gettransaction(fwd_tx)['fee']
        mark_logs("Fee paid for fwd tx: {}".format(fee_fwt), self.nodes,
                  DEBUG_MODE)
        bal_after_fwd_tx = self.nodes[0].getbalance("", 0)
        mark_logs("Node0 balance after fwd: {}".format(bal_after_fwd_tx),
                  self.nodes, DEBUG_MODE)
        assert_equal(bal_before_fwd_tx, bal_after_fwd_tx + fwt_amount -
                     fee_fwt - Decimal(8.75))  # 8.75 is matured coinbase

        assert_equal(self.nodes[0].getscinfo(scid)['balance'], Decimal(0))
        assert_equal(
            self.nodes[0].getscinfo(scid)['immature amounts'][0]['amount'],
            creation_amount)
        assert_equal(
            self.nodes[0].getscinfo(scid)['immature amounts'][1]['amount'],
            fwt_amount)

        mark_logs(
            "Node0 generating 3 more blocks to achieve end of withdrawal epoch",
            self.nodes, DEBUG_MODE)
        self.nodes[0].generate(3)
        self.sync_all()
        assert_equal(self.nodes[0].getscinfo(scid)['balance'],
                     creation_amount + fwt_amount)  # Sc balance has matured
        assert_equal(len(self.nodes[0].getscinfo(scid)['immature amounts']), 0)

        current_height = self.nodes[0].getblockcount()
        epoch_number = (current_height - sc_creating_height +
                        1) // EPOCH_LENGTH - 1
        mark_logs(
            "Current height {}, Sc creation height {}, epoch length {} --> current epoch number {}"
            .format(current_height, sc_creating_height, EPOCH_LENGTH,
                    epoch_number), self.nodes, DEBUG_MODE)
        epoch_block_hash = self.nodes[0].getblockhash(sc_creating_height - 1 +
                                                      ((epoch_number + 1) *
                                                       EPOCH_LENGTH))
        prev_epoch_block_hash = self.nodes[0].getblockhash(sc_creating_height -
                                                           1 +
                                                           ((epoch_number) *
                                                            EPOCH_LENGTH))
        eph_wrong = self.nodes[0].getblockhash(sc_creating_height)
        print "epoch_number = ", epoch_number, ", epoch_block_hash = ", epoch_block_hash

        pkh_node1 = self.nodes[1].getnewaddress("", True)

        #Create proof for WCert
        quality = 0
        proof = mcTest.create_test_proof("sc1", epoch_number, epoch_block_hash,
                                         prev_epoch_block_hash, quality,
                                         constant, [pkh_node1], [bwt_amount])

        mark_logs(
            "Node 0 tries to perform a bwd transfer with insufficient Sc balance...",
            self.nodes, DEBUG_MODE)
        amounts = [{"pubkeyhash": pkh_node1, "amount": bwt_amount_bad}]

        try:
            self.nodes[0].send_certificate(scid, epoch_number, quality,
                                           epoch_block_hash, proof, amounts,
                                           CERT_FEE)
            assert (False)
        except JSONRPCException, e:
            errorString = e.error['message']
            mark_logs(errorString, self.nodes, DEBUG_MODE)

        assert_equal("sidechain has insufficient funds" in errorString, True)
        assert_equal(self.nodes[0].getscinfo(scid)['balance'],
                     creation_amount + fwt_amount)
        assert_equal(len(self.nodes[0].getscinfo(scid)['immature amounts']), 0)

        mark_logs(
            "Node 0 tries to perform a bwd transfer with an invalid epoch number ...",
            self.nodes, DEBUG_MODE)
        amount_cert_1 = [{"pubkeyhash": pkh_node1, "amount": bwt_amount}]

        try:
            self.nodes[0].send_certificate(scid, epoch_number + 1, quality,
                                           epoch_block_hash, proof,
                                           amount_cert_1, CERT_FEE)
            assert (False)
        except JSONRPCException, e:
            errorString = e.error['message']
            mark_logs(errorString, self.nodes, DEBUG_MODE)
示例#19
0
    def run_test(self):

        # forward transfer amounts
        creation_amount = Decimal("0.5")
        fwt_amount = Decimal("50")
        bwt_amount_bad = Decimal("100.0")
        bwt_amount = Decimal("50")

        self.nodes[0].getblockhash(0)

        # node 1 earns some coins, they would be available after 100 blocks
        mark_logs("Node 1 generates 1 block", self.nodes, DEBUG_MODE)
        self.nodes[1].generate(1)
        self.sync_all()

        mark_logs("Node 0 generates 220 block", self.nodes, DEBUG_MODE)
        self.nodes[0].generate(220)
        self.sync_all()

        # SC creation
        bal_before_sc_creation = self.nodes[1].getbalance("", 0)
        mark_logs(
            "Node1 balance before SC creation: {}".format(
                bal_before_sc_creation), self.nodes, DEBUG_MODE)

        #generate wCertVk and constant
        mcTest = MCTestUtils(self.options.tmpdir, self.options.srcdir)
        vk = mcTest.generate_params("sc1")
        constant = generate_random_field_element_hex()

        creating_tx = self.nodes[1].sc_create(EPOCH_LENGTH, "dada",
                                              creation_amount, vk, "",
                                              constant)
        mark_logs(
            "Node 1 created the SC spending {} coins via tx {}.".format(
                creation_amount, creating_tx), self.nodes, DEBUG_MODE)
        self.sync_all()

        decoded_tx = self.nodes[1].getrawtransaction(creating_tx, 1)
        scid = decoded_tx['vsc_ccout'][0]['scid']
        mark_logs("created SC id: {}".format(scid), self.nodes, DEBUG_MODE)

        mark_logs("Node0 confirms Sc creation generating 1 block", self.nodes,
                  DEBUG_MODE)
        self.nodes[0].generate(1)
        sc_creating_height = self.nodes[0].getblockcount()
        self.sync_all()

        # Check node 1 balance following sc creation
        fee_sc_creation = self.nodes[1].gettransaction(creating_tx)['fee']
        mark_logs("Fee paid for SC creation: {}".format(fee_sc_creation),
                  self.nodes, DEBUG_MODE)
        bal_after_sc_creation = self.nodes[1].getbalance("", 0)
        mark_logs(
            "Node1 balance after SC creation: {}".format(
                bal_after_sc_creation), self.nodes, DEBUG_MODE)
        assert_equal(bal_before_sc_creation,
                     bal_after_sc_creation + creation_amount - fee_sc_creation)

        assert_equal(self.nodes[0].getscinfo(scid)['balance'], Decimal(0))
        assert_equal(
            self.nodes[0].getscinfo(scid)['immature amounts'][0]['amount'],
            creation_amount)

        # Fwd Transfer to Sc
        bal_before_fwd_tx = self.nodes[0].getbalance("", 0)
        mark_logs("Node0 balance before fwd tx: {}".format(bal_before_fwd_tx),
                  self.nodes, DEBUG_MODE)
        fwd_tx = self.nodes[0].sc_send("abcd", fwt_amount, scid)
        mark_logs(
            "Node0 transfers {} coins to SC with tx {}...".format(
                fwt_amount, fwd_tx), self.nodes, DEBUG_MODE)
        self.sync_all()

        mark_logs("Node0 confirms fwd transfer generating 1 block", self.nodes,
                  DEBUG_MODE)
        self.nodes[0].generate(1)
        self.sync_all()

        # Check node 0 balance following fwd tx
        fee_fwt = self.nodes[0].gettransaction(fwd_tx)['fee']
        mark_logs("Fee paid for fwd tx: {}".format(fee_fwt), self.nodes,
                  DEBUG_MODE)
        bal_after_fwd_tx = self.nodes[0].getbalance("", 0)
        mark_logs("Node0 balance after fwd: {}".format(bal_after_fwd_tx),
                  self.nodes, DEBUG_MODE)
        assert_equal(bal_before_fwd_tx, bal_after_fwd_tx + fwt_amount -
                     fee_fwt - Decimal(8.75))  # 8.75 is matured coinbase

        assert_equal(self.nodes[0].getscinfo(scid)['balance'], Decimal(0))
        assert_equal(
            self.nodes[0].getscinfo(scid)['immature amounts'][0]['amount'],
            creation_amount)
        assert_equal(
            self.nodes[0].getscinfo(scid)['immature amounts'][1]['amount'],
            fwt_amount)

        mark_logs(
            "Node0 generating 3 more blocks to achieve end of withdrawal epoch",
            self.nodes, DEBUG_MODE)
        self.nodes[0].generate(3)
        self.sync_all()
        assert_equal(self.nodes[0].getscinfo(scid)['balance'],
                     creation_amount + fwt_amount)  # Sc balance has matured
        assert_equal(len(self.nodes[0].getscinfo(scid)['immature amounts']), 0)

        current_height = self.nodes[0].getblockcount()
        epoch_number = (current_height - sc_creating_height +
                        1) // EPOCH_LENGTH - 1
        mark_logs(
            "Current height {}, Sc creation height {}, epoch length {} --> current epoch number {}"
            .format(current_height, sc_creating_height, EPOCH_LENGTH,
                    epoch_number), self.nodes, DEBUG_MODE)
        epoch_block_hash = self.nodes[0].getblockhash(sc_creating_height - 1 +
                                                      ((epoch_number + 1) *
                                                       EPOCH_LENGTH))
        prev_epoch_block_hash = self.nodes[0].getblockhash(sc_creating_height -
                                                           1 +
                                                           ((epoch_number) *
                                                            EPOCH_LENGTH))
        eph_wrong = self.nodes[0].getblockhash(sc_creating_height)
        print "epoch_number = ", epoch_number, ", epoch_block_hash = ", epoch_block_hash

        pkh_node1 = self.nodes[1].getnewaddress("", True)

        #Create proof for WCert
        quality = 0
        proof = mcTest.create_test_proof("sc1", epoch_number, epoch_block_hash,
                                         prev_epoch_block_hash, quality,
                                         constant, [pkh_node1], [bwt_amount])

        mark_logs(
            "Node 0 tries to perform a bwd transfer with insufficient Sc balance...",
            self.nodes, DEBUG_MODE)
        amounts = [{"pubkeyhash": pkh_node1, "amount": bwt_amount_bad}]

        try:
            self.nodes[0].send_certificate(scid, epoch_number, quality,
                                           epoch_block_hash, proof, amounts,
                                           CERT_FEE)
            assert (False)
        except JSONRPCException, e:
            errorString = e.error['message']
            mark_logs(errorString, self.nodes, DEBUG_MODE)
示例#20
0
    def run_test(self):
        def get_spendable(nodeIdx, min_amount):
            # get a UTXO for setting fee
            utx = False
            listunspent = self.nodes[nodeIdx].listunspent()
            for aUtx in listunspent:
                if aUtx['amount'] > min_amount:
                    utx = aUtx
                    change = aUtx['amount'] - min_amount
                    break

            if utx == False:
                pprint.pprint(listunspent)

            assert_equal(utx != False, True)
            return utx, change

        '''
        Testing the capabilities of the api for creating raw certificates and handling their decoding.
        Negative tests are also performed by specifying wrong params and incorrect pkey for the signing
        '''

        # forward transfer amount
        cr_amount = Decimal("5.0")
        bt_amount = Decimal("4.0")
        sc_amount = cr_amount

        # node 1 earns some coins, they would be available after 100 blocks
        mark_logs("Node 1 generates 1 block", self.nodes, DEBUG_MODE)
        self.nodes[1].generate(1)
        self.sync_all()

        mark_logs("Node 0 generates 1 block", self.nodes, DEBUG_MODE)
        self.nodes[0].generate(1)
        self.sync_all()
        mark_logs("Node 3 generates {} block".format(MINIMAL_SC_HEIGHT - 1),
                  self.nodes, DEBUG_MODE)
        self.nodes[3].generate(MINIMAL_SC_HEIGHT - 1)
        self.sync_all()

        # node 1 has just the coinbase which is now mature
        bal_before = self.nodes[1].getbalance("", 0)

        # create a sc via createraw cmd
        mark_logs(
            "Node 1 creates the SC spending " + str(sc_amount) + " coins ...",
            self.nodes, DEBUG_MODE)
        sc_address = "fade"

        #generate vk and constant for this sidechain
        mcTest = CertTestUtils(self.options.tmpdir, self.options.srcdir)
        vk = mcTest.generate_params("sc1")
        constant = generate_random_field_element_hex()

        sc_cr = [{
            "version": 0,
            "epoch_length": EPOCH_LENGTH,
            "amount": cr_amount,
            "address": sc_address,
            "wCertVk": vk,
            "constant": constant
        }]
        sc_ft = []
        raw_tx = self.nodes[1].createrawtransaction([], {}, [], sc_cr, sc_ft)
        funded_tx = self.nodes[1].fundrawtransaction(raw_tx)
        signed_tx = self.nodes[1].signrawtransaction(funded_tx['hex'])
        creating_tx = self.nodes[1].sendrawtransaction(signed_tx['hex'])
        self.sync_all()

        decoded_tx = self.nodes[1].getrawtransaction(creating_tx, 1)
        scid = decoded_tx['vsc_ccout'][0]['scid']
        scid_swapped = str(swap_bytes(scid))
        mark_logs("created SC id: {}".format(scid), self.nodes, DEBUG_MODE)

        #retrieve previous_end_epoch_mc_b_hash
        current_height = self.nodes[3].getblockcount()
        mark_logs("Node3 generating {} blocks".format(EPOCH_LENGTH),
                  self.nodes, DEBUG_MODE)
        self.nodes[3].generate(EPOCH_LENGTH)
        self.sync_all()

        epoch_number, epoch_cum_tree_hash = get_epoch_data(
            scid, self.nodes[0], EPOCH_LENGTH)

        # save them for the last test
        epn_0 = epoch_number
        epoch_cum_tree_hash_0 = epoch_cum_tree_hash

        # -------------------------- end epoch

        sc_funds_pre = self.nodes[3].getscinfo(scid)['items'][0]['balance']

        addr_node2 = self.nodes[2].getnewaddress()

        mark_logs("Node3 generating 2 block, overcoming safeguard", self.nodes,
                  DEBUG_MODE)
        self.nodes[3].generate(2)
        self.sync_all()

        # create wCert proof
        quality = 0
        proof = mcTest.create_test_proof("sc1", scid_swapped, epoch_number,
                                         quality, MBTR_SC_FEE, FT_SC_FEE,
                                         epoch_cum_tree_hash, constant,
                                         [addr_node2], [bt_amount])

        utx, change = get_spendable(0, CERT_FEE)
        raw_inputs = [{'txid': utx['txid'], 'vout': utx['vout']}]
        raw_outs = {self.nodes[0].getnewaddress(): change}

        raw_bwt_outs = [{"address": addr_node2, "amount": bt_amount}]
        raw_params = {
            "scid": scid,
            "quality": quality,
            "endEpochCumScTxCommTreeRoot": epoch_cum_tree_hash,
            "scProof": proof,
            "withdrawalEpochNumber": epoch_number
        }
        raw_cert = []
        cert = []

        try:
            raw_cert = self.nodes[0].createrawcertificate(
                raw_inputs, raw_outs, raw_bwt_outs, raw_params)
            signed_cert = self.nodes[0].signrawtransaction(raw_cert)
        except JSONRPCException, e:
            errorString = e.error['message']
            print "\n======> ", errorString
            assert_true(False)
示例#21
0
    def run_test(self):
        NODE_LIST = self.nodes

        self.nodes[0].generate(
            1)  # Mine a block to leave initial block download
        self.sync_all()

        sc_fork_reached = False
        currentHeight = self.nodes[0].getblockcount()
        mark_logs(("active chain height = %d: testing before sidechain fork" %
                   currentHeight), self.nodes, DEBUG_MODE)
        self.doTest(sc_fork_reached)

        # reach the height where the next block is the last before the fork point where certificates are supported
        delta = MINIMAL_SC_HEIGHT - currentHeight - 2
        self.nodes[0].generate(delta)
        self.sync_all()

        mark_logs((
            "active chain height = %d: testing last block before sidechain fork"
            % self.nodes[0].getblockcount()), self.nodes, DEBUG_MODE)
        self.doTestJustBeforeScFork()

        # reach the fork where certificates are supported
        self.nodes[0].generate(1)
        self.sync_all()

        mark_logs((
            "active chain height = %d: testing block which will be at sidechain fork"
            % self.nodes[0].getblockcount()), self.nodes, DEBUG_MODE)
        sc_fork_reached = True

        # create a sidechain and a certificate for it in the mempool
        mcTest = CertTestUtils(self.options.tmpdir, self.options.srcdir)
        vk = mcTest.generate_params("sc1")
        constant = generate_random_field_element_hex()

        cmdInput = {
            'version': 0,
            'withdrawalEpochLength': SC_EPOCH_LENGTH,
            'toaddress': "dada",
            'amount': SC_CREATION_AMOUNT,
            'wCertVk': vk,
            'customData': "bb" * 1024,
            'constant': constant
        }
        ret = self.nodes[1].sc_create(cmdInput)
        creating_tx = ret['txid']
        scid = ret['scid']
        self.sync_all()

        decoded_tx = self.nodes[1].getrawtransaction(creating_tx, 1)
        assert_equal(scid, decoded_tx['vsc_ccout'][0]['scid'])
        mark_logs("created SC id: {}".format(scid), self.nodes, DEBUG_MODE)

        current_height = self.nodes[1].getblockcount()
        block_list = self.nodes[0].generate(SC_EPOCH_LENGTH)
        self.sync_all()

        addr_node0 = self.nodes[0].getnewaddress()
        amounts = [{"address": addr_node0, "amount": SC_CERT_AMOUNT}]

        #create wCert proof
        epoch_cum_tree_hash = self.nodes[0].getblock(
            block_list[-1])['scCumTreeHash']
        ftScFee = 0.1
        mbtrScFee = 0.1
        fee = 0.000023

        scid_swapped = str(swap_bytes(scid))
        proof = mcTest.create_test_proof("sc1", scid_swapped, 0, 0, mbtrScFee,
                                         ftScFee, epoch_cum_tree_hash,
                                         constant, [addr_node0],
                                         [SC_CERT_AMOUNT])
        cert = self.nodes[0].sc_send_certificate(scid, 0, 0,
                                                 epoch_cum_tree_hash, proof,
                                                 amounts, ftScFee, mbtrScFee,
                                                 fee)
        self.sync_all()
        assert_true(cert in self.nodes[0].getrawmempool())
        mark_logs("cert issued : {}".format(cert), self.nodes, DEBUG_MODE)

        # just one more tx, for having 3 generic txobjs and testing malleability of cert (Test 4)
        tx = self.nodes[0].sendtoaddress(self.nodes[0].getnewaddress(), 0.01)
        self.sync_all()
        assert_true(tx in self.nodes[0].getrawmempool())

        mark_logs("starting test: fork{}".format(sc_fork_reached), self.nodes,
                  DEBUG_MODE)
        self.doTest(sc_fork_reached)

        self.nodes[0].generate(1)
        self.sync_all()
示例#22
0
        decoded_cert_pre = self.nodes[0].decoderawtransaction(raw_cert)
        decoded_cert_pre_list = sorted(decoded_cert_pre.items())

        mark_logs(
            "Node0 sending raw certificate for epoch {}, expecting failure...".
            format(epoch_number), self.nodes, DEBUG_MODE)
        # we expect it to fail because beyond the safeguard
        try:
            cert = self.nodes[0].sendrawtransaction(signed_cert['hex'])
            assert_true(False)
        except JSONRPCException, e:
            errorString = e.error['message']
            print "======> ", errorString, "\n"

        mark_logs(
            "Node0 invalidates last block, thus shortening the chain by one and returning in the safe margin",
            self.nodes, DEBUG_MODE)
        self.nodes[0].invalidateblock(self.nodes[0].getbestblockhash())
        sync_mempools(self.nodes[1:3])

        mark_logs(
            "Node0 sending raw certificate for epoch {}, expecting success".
            format(epoch_number), self.nodes, DEBUG_MODE)
        try:
            cert = self.nodes[0].sendrawtransaction(signed_cert['hex'])
        except JSONRPCException, e:
            errorString = e.error['message']
            print "\n======> ", errorString
            assert_true(False)

        decoded_cert_pre = self.nodes[0].decoderawtransaction(
示例#23
0
class sc_rawcert(BitcoinTestFramework):

    alert_filename = None

    def setup_chain(self, split=False):
        print("Initializing test directory " + self.options.tmpdir)
        initialize_chain_clean(self.options.tmpdir, NUMB_OF_NODES)
        self.alert_filename = os.path.join(self.options.tmpdir, "alert.txt")
        with open(self.alert_filename, 'w'):
            pass  # Just open then close to create zero-length file

    def setup_network(self, split=False):
        self.nodes = []

        self.nodes = start_nodes(
            NUMB_OF_NODES,
            self.options.tmpdir,
            extra_args=[[
                '-debug=py', '-debug=sc', '-debug=mempool', '-debug=net',
                '-debug=cert', '-scproofqueuesize=0', '-logtimemicros=1',
                '-txindex=1', '-zapwallettxes=2'
            ]] * NUMB_OF_NODES)

        for idx, _ in enumerate(self.nodes):
            if idx < (NUMB_OF_NODES - 1):
                connect_nodes_bi(self.nodes, idx, idx + 1)

        sync_blocks(self.nodes[1:NUMB_OF_NODES])
        sync_mempools(self.nodes[1:NUMB_OF_NODES])
        self.is_network_split = split
        self.sync_all()

    def run_test(self):
        def get_spendable(nodeIdx, min_amount):
            # get a UTXO for setting fee
            utx = False
            listunspent = self.nodes[nodeIdx].listunspent()
            for aUtx in listunspent:
                if aUtx['amount'] > min_amount:
                    utx = aUtx
                    change = aUtx['amount'] - min_amount
                    break

            if utx == False:
                pprint.pprint(listunspent)

            assert_equal(utx != False, True)
            return utx, change

        '''
        Testing the capabilities of the api for creating raw certificates and handling their decoding.
        Negative tests are also performed by specifying wrong params and incorrect pkey for the signing
        '''

        # forward transfer amount
        cr_amount = Decimal("5.0")
        bt_amount = Decimal("4.0")
        sc_amount = cr_amount

        # node 1 earns some coins, they would be available after 100 blocks
        mark_logs("Node 1 generates 1 block", self.nodes, DEBUG_MODE)
        self.nodes[1].generate(1)
        self.sync_all()

        mark_logs("Node 0 generates 1 block", self.nodes, DEBUG_MODE)
        self.nodes[0].generate(1)
        self.sync_all()
        mark_logs("Node 3 generates {} block".format(MINIMAL_SC_HEIGHT - 1),
                  self.nodes, DEBUG_MODE)
        self.nodes[3].generate(MINIMAL_SC_HEIGHT - 1)
        self.sync_all()

        # node 1 has just the coinbase which is now mature
        bal_before = self.nodes[1].getbalance("", 0)

        # create a sc via createraw cmd
        mark_logs(
            "Node 1 creates the SC spending " + str(sc_amount) + " coins ...",
            self.nodes, DEBUG_MODE)
        sc_address = "fade"

        #generate vk and constant for this sidechain
        mcTest = CertTestUtils(self.options.tmpdir, self.options.srcdir)
        vk = mcTest.generate_params("sc1")
        constant = generate_random_field_element_hex()

        sc_cr = [{
            "version": 0,
            "epoch_length": EPOCH_LENGTH,
            "amount": cr_amount,
            "address": sc_address,
            "wCertVk": vk,
            "constant": constant
        }]
        sc_ft = []
        raw_tx = self.nodes[1].createrawtransaction([], {}, [], sc_cr, sc_ft)
        funded_tx = self.nodes[1].fundrawtransaction(raw_tx)
        signed_tx = self.nodes[1].signrawtransaction(funded_tx['hex'])
        creating_tx = self.nodes[1].sendrawtransaction(signed_tx['hex'])
        self.sync_all()

        decoded_tx = self.nodes[1].getrawtransaction(creating_tx, 1)
        scid = decoded_tx['vsc_ccout'][0]['scid']
        scid_swapped = str(swap_bytes(scid))
        mark_logs("created SC id: {}".format(scid), self.nodes, DEBUG_MODE)

        #retrieve previous_end_epoch_mc_b_hash
        current_height = self.nodes[3].getblockcount()
        mark_logs("Node3 generating {} blocks".format(EPOCH_LENGTH),
                  self.nodes, DEBUG_MODE)
        self.nodes[3].generate(EPOCH_LENGTH)
        self.sync_all()

        epoch_number, epoch_cum_tree_hash = get_epoch_data(
            scid, self.nodes[0], EPOCH_LENGTH)

        # save them for the last test
        epn_0 = epoch_number
        epoch_cum_tree_hash_0 = epoch_cum_tree_hash

        # -------------------------- end epoch

        sc_funds_pre = self.nodes[3].getscinfo(scid)['items'][0]['balance']

        addr_node2 = self.nodes[2].getnewaddress()

        mark_logs("Node3 generating 2 block, overcoming safeguard", self.nodes,
                  DEBUG_MODE)
        self.nodes[3].generate(2)
        self.sync_all()

        # create wCert proof
        quality = 0
        proof = mcTest.create_test_proof("sc1", scid_swapped, epoch_number,
                                         quality, MBTR_SC_FEE, FT_SC_FEE,
                                         epoch_cum_tree_hash, constant,
                                         [addr_node2], [bt_amount])

        utx, change = get_spendable(0, CERT_FEE)
        raw_inputs = [{'txid': utx['txid'], 'vout': utx['vout']}]
        raw_outs = {self.nodes[0].getnewaddress(): change}

        raw_bwt_outs = [{"address": addr_node2, "amount": bt_amount}]
        raw_params = {
            "scid": scid,
            "quality": quality,
            "endEpochCumScTxCommTreeRoot": epoch_cum_tree_hash,
            "scProof": proof,
            "withdrawalEpochNumber": epoch_number
        }
        raw_cert = []
        cert = []

        try:
            raw_cert = self.nodes[0].createrawcertificate(
                raw_inputs, raw_outs, raw_bwt_outs, raw_params)
            signed_cert = self.nodes[0].signrawtransaction(raw_cert)
        except JSONRPCException, e:
            errorString = e.error['message']
            print "\n======> ", errorString
            assert_true(False)

        decoded_cert_pre = self.nodes[0].decoderawtransaction(raw_cert)
        decoded_cert_pre_list = sorted(decoded_cert_pre.items())

        mark_logs(
            "Node0 sending raw certificate for epoch {}, expecting failure...".
            format(epoch_number), self.nodes, DEBUG_MODE)
        # we expect it to fail because beyond the safeguard
        try:
            cert = self.nodes[0].sendrawtransaction(signed_cert['hex'])
            assert_true(False)
        except JSONRPCException, e:
            errorString = e.error['message']
            print "======> ", errorString, "\n"
示例#24
0
    def run_test(self):
        '''
        Create a SC, advance two epochs, move to the limit of the safe guard and then split the network. 
        One network part sends fwt, mbtr and a certificate, all of them are stored in mempool.
        The other network part sends a certificate and mines one block reaching a longer chain height.
        When the network is joined, verify that the SC is alive, fwt is still in the mempool of the the
        loosing network part, but cert and mbtr have been removed from those mempool.
        '''

        # prepare some coins
        self.nodes[3].generate(1)
        self.sync_all()
        self.nodes[2].generate(1)
        self.sync_all()
        self.nodes[1].generate(1)
        self.sync_all()
        self.nodes[0].generate(MINIMAL_SC_HEIGHT - 3)
        self.sync_all()
        self.nodes[0].generate(1)
        self.sync_all()

        print "Node0 Chain h = ", self.nodes[0].getblockcount()

        sc_address = "0000000000000000000000000000000000000000000000000000000000000abc"
        sc_epoch_len = EPOCH_LENGTH
        sc_cr_amount = Decimal('12.00000000')

        certMcTest = CertTestUtils(self.options.tmpdir, self.options.srcdir)

        # generate wCertVk and constant
        vk = certMcTest.generate_params("sc1")
        constant = generate_random_field_element_hex()

        cmdInput = {
            'version': 0,
            'withdrawalEpochLength': sc_epoch_len,
            'amount': sc_cr_amount,
            'toaddress': sc_address,
            'wCertVk': vk,
            'constant': constant,
            'mainchainBackwardTransferRequestDataLength': 1
        }

        res = self.nodes[0].sc_create(cmdInput)
        tx = res['txid']
        scid = res['scid']
        scid_swapped = str(swap_bytes(scid))
        self.sync_all()
        mark_logs("tx {} created SC {}".format(tx, scid), self.nodes,
                  DEBUG_MODE)

        dest_addr = self.nodes[1].getnewaddress()
        fe1 = [generate_random_field_element_hex()]

        # advance two epochs
        mark_logs("\nLet 2 epochs pass by...", self.nodes, DEBUG_MODE)

        cert, epoch_number = advance_epoch(certMcTest, self.nodes[0],
                                           self.sync_all, scid, "sc1",
                                           constant, sc_epoch_len)

        mark_logs(
            "\n==> certificate for epoch {} {}".format(epoch_number, cert),
            self.nodes, DEBUG_MODE)

        cert, epoch_number = advance_epoch(certMcTest, self.nodes[0],
                                           self.sync_all, scid, "sc1",
                                           constant, sc_epoch_len)

        mark_logs(
            "\n==> certificate for epoch {} {}l".format(epoch_number, cert),
            self.nodes, DEBUG_MODE)

        ceas_height = self.nodes[0].getscinfo(
            scid, False, False)['items'][0]['ceasingHeight']
        numbBlocks = ceas_height - self.nodes[0].getblockcount(
        ) + sc_epoch_len - 1
        print "Node0 Chain h = ", self.nodes[0].getblockcount()

        mark_logs(
            "\nNode0 generates {} block reaching the sg for the next epoch".
            format(numbBlocks), self.nodes, DEBUG_MODE)
        self.nodes[0].generate(numbBlocks)
        self.sync_all()
        print "Node0 Chain h = ", self.nodes[0].getblockcount()

        bal_initial = self.nodes[0].getscinfo(scid, False,
                                              False)['items'][0]['balance']

        #============================================================================================
        mark_logs("\nSplit network", self.nodes, DEBUG_MODE)
        self.split_network()
        mark_logs("The network is split: 0-1-2 .. 3", self.nodes, DEBUG_MODE)

        # Network part 0-1-2
        print "------------------"
        # use different nodes for sending txes and cert in order to be sure there are no dependancies from each other
        fwt_amount = Decimal("2.0")
        mc_return_address = self.nodes[0].getnewaddress()
        mark_logs(
            "\nNTW part 1) Node0 sends {} coins to SC".format(fwt_amount),
            self.nodes, DEBUG_MODE)
        cmdInput = [{
            'toaddress': "abcd",
            'amount': fwt_amount,
            "scid": scid,
            'mcReturnAddress': mc_return_address
        }]
        tx_fwd = self.nodes[0].sc_send(cmdInput)
        sync_mempools(self.nodes[0:3])

        mark_logs("              Check fwd tx {} is in mempool".format(tx_fwd),
                  self.nodes, DEBUG_MODE)
        assert_true(tx_fwd in self.nodes[0].getrawmempool())

        outputs = [{
            'vScRequestData': fe1,
            'scFee': Decimal("0.001"),
            'scid': scid,
            'mcDestinationAddress': dest_addr
        }]
        cmdParms = {"minconf": 0, "fee": 0.0}
        mark_logs("\nNTW part 1) Node1 creates a tx with a bwt request",
                  self.nodes, DEBUG_MODE)
        try:
            tx_bwt = self.nodes[1].sc_request_transfer(outputs, cmdParms)
        except JSONRPCException, e:
            errorString = e.error['message']
            mark_logs(errorString, self.nodes, DEBUG_MODE)
            assert_true(False)
示例#25
0
class CertMempoolCleanupSplit(BitcoinTestFramework):
    def setup_chain(self):
        print("Initializing test directory " + self.options.tmpdir)
        initialize_chain_clean(self.options.tmpdir, NUMB_OF_NODES)

    def setup_network(self, split=False):
        self.nodes = start_nodes(
            NUMB_OF_NODES,
            self.options.tmpdir,
            extra_args=[[
                '-logtimemicros=1', '-scproofqueuesize=0', '-debug=sc',
                '-debug=py', '-debug=mempool', '-debug=net', '-debug=bench'
            ]] * NUMB_OF_NODES)

        if not split:
            # 2 and 3 are joint only if split==false
            connect_nodes_bi(self.nodes, 2, 3)
            sync_blocks(self.nodes[2:4])
            sync_mempools(self.nodes[2:4])

        connect_nodes_bi(self.nodes, 0, 1)
        connect_nodes_bi(self.nodes, 1, 2)
        self.is_network_split = split
        self.sync_all()

    def split_network(self):
        # Split the network of three nodes into nodes 0-1-2 and 3.
        assert not self.is_network_split
        disconnect_nodes(self.nodes[2], 3)
        disconnect_nodes(self.nodes[3], 2)
        self.is_network_split = True

    def join_network(self):
        # Join the (previously split) network pieces together: 0-1-2-3
        assert self.is_network_split
        connect_nodes_bi(self.nodes, 2, 3)
        connect_nodes_bi(self.nodes, 3, 2)
        time.sleep(2)
        self.is_network_split = False

    def run_test(self):
        '''
        Create a SC, advance two epochs, move to the limit of the safe guard and then split the network. 
        One network part sends fwt, mbtr and a certificate, all of them are stored in mempool.
        The other network part sends a certificate and mines one block reaching a longer chain height.
        When the network is joined, verify that the SC is alive, fwt is still in the mempool of the the
        loosing network part, but cert and mbtr have been removed from those mempool.
        '''

        # prepare some coins
        self.nodes[3].generate(1)
        self.sync_all()
        self.nodes[2].generate(1)
        self.sync_all()
        self.nodes[1].generate(1)
        self.sync_all()
        self.nodes[0].generate(MINIMAL_SC_HEIGHT - 3)
        self.sync_all()
        self.nodes[0].generate(1)
        self.sync_all()

        print "Node0 Chain h = ", self.nodes[0].getblockcount()

        sc_address = "0000000000000000000000000000000000000000000000000000000000000abc"
        sc_epoch_len = EPOCH_LENGTH
        sc_cr_amount = Decimal('12.00000000')

        certMcTest = CertTestUtils(self.options.tmpdir, self.options.srcdir)

        # generate wCertVk and constant
        vk = certMcTest.generate_params("sc1")
        constant = generate_random_field_element_hex()

        cmdInput = {
            'version': 0,
            'withdrawalEpochLength': sc_epoch_len,
            'amount': sc_cr_amount,
            'toaddress': sc_address,
            'wCertVk': vk,
            'constant': constant,
            'mainchainBackwardTransferRequestDataLength': 1
        }

        res = self.nodes[0].sc_create(cmdInput)
        tx = res['txid']
        scid = res['scid']
        scid_swapped = str(swap_bytes(scid))
        self.sync_all()
        mark_logs("tx {} created SC {}".format(tx, scid), self.nodes,
                  DEBUG_MODE)

        dest_addr = self.nodes[1].getnewaddress()
        fe1 = [generate_random_field_element_hex()]

        # advance two epochs
        mark_logs("\nLet 2 epochs pass by...", self.nodes, DEBUG_MODE)

        cert, epoch_number = advance_epoch(certMcTest, self.nodes[0],
                                           self.sync_all, scid, "sc1",
                                           constant, sc_epoch_len)

        mark_logs(
            "\n==> certificate for epoch {} {}".format(epoch_number, cert),
            self.nodes, DEBUG_MODE)

        cert, epoch_number = advance_epoch(certMcTest, self.nodes[0],
                                           self.sync_all, scid, "sc1",
                                           constant, sc_epoch_len)

        mark_logs(
            "\n==> certificate for epoch {} {}l".format(epoch_number, cert),
            self.nodes, DEBUG_MODE)

        ceas_height = self.nodes[0].getscinfo(
            scid, False, False)['items'][0]['ceasingHeight']
        numbBlocks = ceas_height - self.nodes[0].getblockcount(
        ) + sc_epoch_len - 1
        print "Node0 Chain h = ", self.nodes[0].getblockcount()

        mark_logs(
            "\nNode0 generates {} block reaching the sg for the next epoch".
            format(numbBlocks), self.nodes, DEBUG_MODE)
        self.nodes[0].generate(numbBlocks)
        self.sync_all()
        print "Node0 Chain h = ", self.nodes[0].getblockcount()

        bal_initial = self.nodes[0].getscinfo(scid, False,
                                              False)['items'][0]['balance']

        #============================================================================================
        mark_logs("\nSplit network", self.nodes, DEBUG_MODE)
        self.split_network()
        mark_logs("The network is split: 0-1-2 .. 3", self.nodes, DEBUG_MODE)

        # Network part 0-1-2
        print "------------------"
        # use different nodes for sending txes and cert in order to be sure there are no dependancies from each other
        fwt_amount = Decimal("2.0")
        mc_return_address = self.nodes[0].getnewaddress()
        mark_logs(
            "\nNTW part 1) Node0 sends {} coins to SC".format(fwt_amount),
            self.nodes, DEBUG_MODE)
        cmdInput = [{
            'toaddress': "abcd",
            'amount': fwt_amount,
            "scid": scid,
            'mcReturnAddress': mc_return_address
        }]
        tx_fwd = self.nodes[0].sc_send(cmdInput)
        sync_mempools(self.nodes[0:3])

        mark_logs("              Check fwd tx {} is in mempool".format(tx_fwd),
                  self.nodes, DEBUG_MODE)
        assert_true(tx_fwd in self.nodes[0].getrawmempool())

        outputs = [{
            'vScRequestData': fe1,
            'scFee': Decimal("0.001"),
            'scid': scid,
            'mcDestinationAddress': dest_addr
        }]
        cmdParms = {"minconf": 0, "fee": 0.0}
        mark_logs("\nNTW part 1) Node1 creates a tx with a bwt request",
                  self.nodes, DEBUG_MODE)
        try:
            tx_bwt = self.nodes[1].sc_request_transfer(outputs, cmdParms)
        except JSONRPCException, e:
            errorString = e.error['message']
            mark_logs(errorString, self.nodes, DEBUG_MODE)
            assert_true(False)

        sync_mempools(self.nodes[0:3])

        mark_logs("              Check bwd tx {} is in mempool".format(tx_bwt),
                  self.nodes, DEBUG_MODE)
        assert_true(tx_bwt in self.nodes[0].getrawmempool())

        mark_logs("\nNTW part 1) Node2 sends a certificate", self.nodes,
                  DEBUG_MODE)
        epoch_number, epoch_cum_tree_hash = get_epoch_data(
            scid, self.nodes[2], sc_epoch_len)

        bt_amount = Decimal("5.0")
        addr_node1 = self.nodes[1].getnewaddress()
        quality = 10

        proof = certMcTest.create_test_proof("sc1", scid_swapped, epoch_number,
                                             quality, MBTR_SC_FEE, FT_SC_FEE,
                                             epoch_cum_tree_hash, constant,
                                             [addr_node1], [bt_amount])

        amount_cert = [{"address": addr_node1, "amount": bt_amount}]
        try:
            cert_bad = self.nodes[2].sc_send_certificate(
                scid, epoch_number, quality, epoch_cum_tree_hash, proof,
                amount_cert, 0, 0, 0.01)
        except JSONRPCException, e:
            errorString = e.error['message']
            print "Send certificate failed with reason {}".format(errorString)
            assert (False)
    def run_test(self):
        '''
        Create a SC, advance two epochs and then let it cease.
        Create two transactions, each one containing a CSW with
        an input value covering the whole sidechain balance.
        Even though the first CSW transaction is still in mempool,
        the second one should be rejected.
        '''

        # prepare some coins
        self.nodes[0].generate(MINIMAL_SC_HEIGHT)
        self.sync_all()

        sc_address = "0000000000000000000000000000000000000000000000000000000000000abc"
        sc_epoch_len = EPOCH_LENGTH
        sc_cr_amount = Decimal('12.00000000')

        certMcTest = CertTestUtils(self.options.tmpdir, self.options.srcdir)
        cswMcTest = CSWTestUtils(self.options.tmpdir, self.options.srcdir)

        # generate wCertVk and constant
        vk = certMcTest.generate_params("sc1")
        cswVk = cswMcTest.generate_params("sc1")
        constant = generate_random_field_element_hex()

        sc_cr = []
        sc_cr.append({
            "version": 0,
            "epoch_length": sc_epoch_len,
            "amount": sc_cr_amount,
            "address": sc_address,
            "wCertVk": vk,
            "wCeasedVk": cswVk,
            "constant": constant
        })

        rawtx = self.nodes[0].createrawtransaction([], {}, [], sc_cr)
        funded_tx = self.nodes[0].fundrawtransaction(rawtx)
        sigRawtx = self.nodes[0].signrawtransaction(funded_tx['hex'])
        finalRawtx = self.nodes[0].sendrawtransaction(sigRawtx['hex'])
        self.sync_all()

        decoded_tx = self.nodes[2].getrawtransaction(finalRawtx, 1)
        scid = decoded_tx['vsc_ccout'][0]['scid']
        mark_logs("created SC id: {}".format(scid), self.nodes, DEBUG_MODE)
        print

        # advance two epochs
        mark_logs("\nLet 2 epochs pass by...", self.nodes, DEBUG_MODE)

        cert, epoch_number = advance_epoch(certMcTest, self.nodes[0],
                                           self.sync_all, scid, "sc1",
                                           constant, sc_epoch_len)

        mark_logs(
            "\n==> certificate for epoch {} {}".format(epoch_number, cert),
            self.nodes, DEBUG_MODE)

        cert, epoch_number = advance_epoch(certMcTest, self.nodes[0],
                                           self.sync_all, scid, "sc1",
                                           constant, sc_epoch_len)

        mark_logs(
            "\n==> certificate for epoch {} {}l".format(epoch_number, cert),
            self.nodes, DEBUG_MODE)

        # mine one block for having last cert in chain
        mark_logs("\nNode0 generates 1 block confirming last cert", self.nodes,
                  DEBUG_MODE)
        self.nodes[0].generate(1)
        self.sync_all()

        mark_logs("Let SC cease... ", self.nodes, DEBUG_MODE)

        nbl = int(sc_epoch_len * 1.5)
        mark_logs("Node0 generates {} blocks".format(nbl), self.nodes,
                  DEBUG_MODE)
        self.nodes[0].generate(nbl)
        self.sync_all()

        # check it is really ceased
        ret = self.nodes[0].getscinfo(scid, False, False)['items'][0]
        assert_equal(ret['state'], "CEASED")

        # and has the expected balance
        sc_bal = self.nodes[0].getscinfo(scid, False,
                                         False)['items'][0]['balance']
        assert_equal(sc_bal, sc_cr_amount)

        mark_logs("\nCreate a CSW withdrawing 90% of the sc balance... ",
                  self.nodes, DEBUG_MODE)

        # CSW sender MC address
        csw_mc_address = self.nodes[0].getnewaddress()

        sc_csw_amount = sc_bal * Decimal("0.9")
        null1 = generate_random_field_element_hex()
        actCertData = self.nodes[0].getactivecertdatahash(scid)['certDataHash']
        print "Active Cert Data Hash: -------> ", actCertData

        ceasingCumScTxCommTree = self.nodes[0].getceasingcumsccommtreehash(
            scid)['ceasingCumScTxCommTree']

        scid_swapped = swap_bytes(scid)
        sc_proof1 = cswMcTest.create_test_proof("sc1", sc_csw_amount,
                                                str(scid_swapped), null1,
                                                csw_mc_address,
                                                ceasingCumScTxCommTree,
                                                actCertData, constant)

        sc_csws = [{
            "amount": sc_csw_amount,
            "senderAddress": csw_mc_address,
            "scId": scid,
            "epoch": 0,
            "nullifier": null1,
            "activeCertData": actCertData,
            "ceasingCumScTxCommTree": ceasingCumScTxCommTree,
            "scProof": sc_proof1
        }]

        # recipient MC address
        taddr_2 = self.nodes[2].getnewaddress()
        sc_csw_tx_outs = {taddr_2: sc_csw_amount}

        rawtx = self.nodes[0].createrawtransaction([], sc_csw_tx_outs, sc_csws)
        funded_tx = self.nodes[0].fundrawtransaction(rawtx)
        sigRawtx = self.nodes[0].signrawtransaction(funded_tx['hex'], None,
                                                    None, "NONE")
        finalRawtx = self.nodes[0].sendrawtransaction(sigRawtx['hex'])
        mark_logs(
            "sent csw 1 {} retrieving {} coins on Node2 behalf".format(
                finalRawtx, sc_csws[0]['amount']), self.nodes, DEBUG_MODE)
        self.sync_all()

        mark_logs("Check csw is in mempool...", self.nodes, DEBUG_MODE)
        assert_true(finalRawtx in self.nodes[2].getrawmempool())

        mark_logs(
            "\nCreate a second CSW withdrawing 90% of the sc balance (should be rejected)... ",
            self.nodes, DEBUG_MODE)

        # CSW sender MC address
        csw_mc_address = self.nodes[0].getnewaddress()

        sc_csw_amount = sc_bal * Decimal("0.9")
        null1 = generate_random_field_element_hex()

        sc_proof1 = cswMcTest.create_test_proof("sc1", sc_csw_amount,
                                                str(scid_swapped), null1,
                                                csw_mc_address,
                                                ceasingCumScTxCommTree,
                                                actCertData, constant)

        sc_csws = [{
            "amount": sc_csw_amount,
            "senderAddress": csw_mc_address,
            "scId": scid,
            "epoch": 0,
            "nullifier": null1,
            "activeCertData": actCertData,
            "ceasingCumScTxCommTree": ceasingCumScTxCommTree,
            "scProof": sc_proof1
        }]

        # recipient MC address
        taddr_2 = self.nodes[2].getnewaddress()
        sc_csw_tx_outs = {taddr_2: sc_csw_amount}

        rawtx = self.nodes[0].createrawtransaction([], sc_csw_tx_outs, sc_csws)
        funded_tx = self.nodes[0].fundrawtransaction(rawtx)
        sigRawtx = self.nodes[0].signrawtransaction(funded_tx['hex'], None,
                                                    None, "NONE")

        try:
            finalRawtx = self.nodes[0].sendrawtransaction(sigRawtx['hex'])
            assert (False)
        except JSONRPCException, e:
            error_string = e.error['message']
            mark_logs(
                "Failed sending csw 2 {} retrieving {} coins on Node2 behalf, error message: {}"
                .format(finalRawtx, sc_csws[0]['amount'],
                        error_string), self.nodes, DEBUG_MODE)
            assert_true("bad-sc-tx-not-applicable" in error_string)
示例#27
0
class SCCreateTest(BitcoinTestFramework):
    alert_filename = None

    def setup_chain(self, split=False):
        print("Initializing test directory " + self.options.tmpdir)
        initialize_chain_clean(self.options.tmpdir, NUMB_OF_NODES)
        self.alert_filename = os.path.join(self.options.tmpdir, "alert.txt")
        with open(self.alert_filename, 'w'):
            pass  # Just open then close to create zero-length file

    def setup_network(self, split=False):

        self.nodes = start_nodes(
            NUMB_OF_NODES,
            self.options.tmpdir,
            extra_args=[[
                "-sccoinsmaturity=%d" % SC_COINS_MAT, '-logtimemicros=1',
                '-debug=sc', '-debug=py', '-debug=mempool', '-debug=net',
                '-debug=bench'
            ]] * NUMB_OF_NODES)

        connect_nodes_bi(self.nodes, 0, 1)
        self.is_network_split = split
        self.sync_all()

    def run_test(self):
        '''
        This test try to create a SC using the command sc_create using invalid parameters and valid parameters.
        '''
        #{"withdrawalEpochLength", "fromaddress", "toaddress", "amount", "minconf", "fee", "customData"};

        # network topology: (0)--(1)

        mark_logs("Node 1 generates 2 block", self.nodes, DEBUG_MODE)
        self.nodes[1].generate(2)
        self.sync_all()

        mark_logs("Node 0 generates {} block".format(MINIMAL_SC_HEIGHT),
                  self.nodes, DEBUG_MODE)
        self.nodes[0].generate(MINIMAL_SC_HEIGHT)
        self.sync_all()

        tx = []
        errorString = ""
        toaddress = "abcdef"

        #generate wCertVk and constant
        mcTest = CertTestUtils(self.options.tmpdir, self.options.srcdir)
        vk = mcTest.generate_params('sc1')
        constant = generate_random_field_element_hex()

        # create with wrong key in input
        #------------------------------------
        amount = 12.0
        fee = 0.000025

        cmdInput = {
            'version': 0,
            'wrong_key': 123,
            'toaddress': toaddress,
            'amount': amount,
            'fee': fee,
            'wCertVk': vk
        }

        mark_logs("\nNode 1 create SC with wrong key in input", self.nodes,
                  DEBUG_MODE)
        try:
            self.nodes[1].sc_create(cmdInput)
            assert_true(False)
        except JSONRPCException, e:
            errorString = e.error['message']
            mark_logs(errorString, self.nodes, DEBUG_MODE)
            assert_true("wrong_key" in errorString)

        # create with duplicate key in input
        #------------------------------------
        cmdInput = FakeDict([('version', 0), ('fee', fee), ('amount', amount),
                             ('amount', 6.0), ('toaddress', str(toaddress)),
                             ('wCertVk', vk)])

        mark_logs("\nNode 1 create SC with duplicate key in input", self.nodes,
                  DEBUG_MODE)
        try:
            self.nodes[1].sc_create(cmdInput)
            assert_true(False)
        except JSONRPCException, e:
            errorString = e.error['message']
            mark_logs(errorString, self.nodes, DEBUG_MODE)
            assert_true("amount" in errorString)
示例#28
0
            self.nodes[0].send_certificate(scid, epoch_number + 1, quality,
                                           epoch_block_hash, proof,
                                           amount_cert_1, CERT_FEE)
            assert (False)
        except JSONRPCException, e:
            errorString = e.error['message']
            mark_logs(errorString, self.nodes, DEBUG_MODE)

        assert_equal("invalid epoch data" in errorString, True)
        assert_equal(
            self.nodes[0].getscinfo(scid)['balance'], creation_amount +
            fwt_amount)  # Sc has not been affected by faulty certificate
        assert_equal(len(self.nodes[0].getscinfo(scid)['immature amounts']), 0)

        mark_logs(
            "Node 0 tries to perform a bwd transfer with an invalid quality ...",
            self.nodes, DEBUG_MODE)

        try:
            self.nodes[0].send_certificate(scid, epoch_number, quality - 1,
                                           epoch_block_hash, proof,
                                           amount_cert_1, CERT_FEE)
            assert (False)
        except JSONRPCException, e:
            errorString = e.error['message']
            mark_logs(errorString, self.nodes, DEBUG_MODE)

        assert_equal("Invalid quality parameter" in errorString, True)
        assert_equal(
            self.nodes[0].getscinfo(scid)['balance'], creation_amount +
            fwt_amount)  # Sc has not been affected by faulty certificate
示例#29
0
                                             quality, MBTR_SC_FEE, FT_SC_FEE,
                                             epoch_cum_tree_hash, constant,
                                             [addr_node1], [bt_amount])

        amount_cert = [{"address": addr_node1, "amount": bt_amount}]
        try:
            cert_bad = self.nodes[2].sc_send_certificate(
                scid, epoch_number, quality, epoch_cum_tree_hash, proof,
                amount_cert, 0, 0, 0.01)
        except JSONRPCException, e:
            errorString = e.error['message']
            print "Send certificate failed with reason {}".format(errorString)
            assert (False)
        sync_mempools(self.nodes[0:3])

        mark_logs("              Check cert {} is in mempool".format(cert_bad),
                  self.nodes, DEBUG_MODE)
        assert_true(cert_bad in self.nodes[0].getrawmempool())
        print "Node0 Chain h = ", self.nodes[0].getblockcount()

        # Network part 2
        #------------------
        mark_logs("\nNTW part 2) Node3 sends a certificate", self.nodes,
                  DEBUG_MODE)
        epoch_number, epoch_cum_tree_hash = get_epoch_data(
            scid, self.nodes[3], sc_epoch_len)

        bt_amount_2 = Decimal("10.0")
        addr_node1 = self.nodes[1].getnewaddress()
        quality = 5

        proof = certMcTest.create_test_proof("sc1", scid_swapped, epoch_number,
示例#30
0
    def doTest(self, sc_fork_reached):

        node = self.nodes[0]

        tmpl = node.getblocktemplate()
        if 'coinbasetxn' not in tmpl:
            rawcoinbase = encodeUNum(tmpl['height'])
            rawcoinbase += b'\x01-'
            hexcoinbase = b2x(rawcoinbase)
            hexoutval = b2x(pack('<Q', tmpl['coinbasevalue']))
            tmpl['coinbasetxn'] = {
                'data':
                '01000000' + '01' +
                '0000000000000000000000000000000000000000000000000000000000000000ffffffff'
                + ('%02x' % (len(rawcoinbase), )) + hexcoinbase + 'fffffffe' +
                '01' + hexoutval + '00' + '00000000'
            }
        txlist = list(
            bytearray(a2b_hex(a['data']))
            for a in (tmpl['coinbasetxn'], ) + tuple(tmpl['transactions']))
        certlist = []

        # if the block supports certificates, add them (if any)
        if tmpl['version'] == SC_CERTIFICATE_BLOCK_VERSION:
            assert_true(sc_fork_reached)
            certlist = list(
                bytearray(a2b_hex(a['data']))
                for a in tuple(tmpl['certificates']))

        # Test 0: Capability advertised
        assert ('proposal' in tmpl['capabilities'])

        # NOTE: This test currently FAILS (regtest mode doesn't enforce block height in coinbase)
        ## Test 1: Bad height in coinbase
        #txlist[0][4+1+36+1+1] += 1
        #assert_template(node, tmpl, txlist, 'FIXME')
        #txlist[0][4+1+36+1+1] -= 1

        # Test 2: Bad input hash for gen tx
        txlist[0][4 + 1] += 1
        assert_template(node, tmpl, txlist, certlist, 'bad-cb-missing')
        txlist[0][4 + 1] -= 1

        # Test 3: Truncated final tx
        lastbyte = txlist[-1].pop()
        try:
            assert_template(node, tmpl, txlist, certlist, 'n/a')
        except JSONRPCException:
            pass  # Expected
        txlist[-1].append(lastbyte)

        # Check for merkle tree malleability (CVE-2012-2459): repeating sequences
        # of transactions (or certificates) in a block without affecting the merkle root,
        # while still invalidating it.
        if len(certlist) == 0:
            # Test 4: Add an invalid tx to the end (duplicate of gen tx)
            txlist.append(txlist[0])
            assert_template(node, tmpl, txlist, certlist, 'bad-txns-duplicate')
            txlist.pop()
        else:
            # Test 4: Add an invalid cert to the end (duplicate of cert)
            certlist.append(certlist[0])
            assert_template(node, tmpl, txlist, certlist, 'bad-txns-duplicate')
            certlist.pop()

        # Test 5: Add an invalid tx to the end (non-duplicate)
        txlist.append(bytearray(txlist[0]))
        txlist[-1][4 + 1] = b'\xff'
        #! This transaction is failing sooner than intended in the
        #! test because of the lack of an op-checkblockheight
        #assert_template(node, tmpl, txlist, 'bad-txns-inputs-missingorspent')
        assert_template(node, tmpl, txlist, certlist,
                        'op-checkblockatheight-needed')
        txlist.pop()

        # Test 6: Future tx lock time
        txlist[0][
            49] -= 1  # in template nSequence is equal 0xffffffff, in such case it disables nLockTime. Decrease nSequence to enable lock time check.
        txlist[0][-4:] = b'\xff\xff\xff\xff'  # set nLockTime far in future
        assert_template(node, tmpl, txlist, certlist, 'bad-txns-nonfinal')
        txlist[0][-4:] = b'\0\0\0\0'

        # Test 7: Bad tx count
        txlist.append(b'')
        try:
            assert_template(node, tmpl, txlist, certlist, 'n/a')
        except JSONRPCException:
            pass  # Expected
        txlist.pop()

        # Test 8: Bad bits
        realbits = tmpl['bits']
        tmpl['bits'] = '1c0000ff'  # impossible in the real world
        assert_template(node, tmpl, txlist, certlist, 'bad-diffbits')
        tmpl['bits'] = realbits

        # Test 9: Bad merkle root
        rawtmpl = template_to_bytes(tmpl, txlist, certlist)
        rawtmpl[4 + 32] = (rawtmpl[4 + 32] + 1) % 0x100
        rsp = node.getblocktemplate({'data': b2x(rawtmpl), 'mode': 'proposal'})
        if rsp != 'bad-txnmrklroot':
            raise AssertionError('unexpected: %s' % (rsp, ))

        # Test 10: Bad timestamps
        realtime = tmpl['curtime']
        tmpl['curtime'] = 0x7fffffff
        if sc_fork_reached == False:
            assert_template(node, tmpl, txlist, certlist, 'time-too-new')
        else:
            # if we reached sc fork we also have passed timeblock fork and the error changes
            assert_template(node, tmpl, txlist, certlist,
                            'time-too-far-ahead-of-mtp')
        tmpl['curtime'] = 0
        assert_template(node, tmpl, txlist, certlist, 'time-too-old')
        tmpl['curtime'] = realtime

        if sc_fork_reached == False:
            # Test 11: Valid block
            assert_template(node, tmpl, txlist, certlist, None)
        else:
            assert_true(len(certlist) != 0)
            # compute commitment for the only contribution of certificate (we have no sctx/btr)
            '''
            TODO - this test is commented out since in this branch the sc commitment tree is computed in a different way
            in mainchain and it would trigger an error 
            -----
            TxsHash = dblsha(SC_NULL_HASH + SC_NULL_HASH)
            WCertHash = dblsha(certlist[0])
            scid = certlist[0][4:4+32]
            SCHash = dblsha(TxsHash + WCertHash + scid)
            assert_template(node, tmpl, txlist, certlist, None, SCHash)
            '''

        # Test 12: Orphan block
        orig_val = tmpl['previousblockhash']
        tmpl['previousblockhash'] = 'ff00' * 16
        assert_template(node, tmpl, txlist, certlist,
                        'inconclusive-not-best-prevblk')
        tmpl['previousblockhash'] = orig_val

        if sc_fork_reached == True:
            assert_true(len(certlist) != 0)
            # cert only specific tests

            # Test 13: Bad cert count
            mark_logs("Bad cert count (expecting failure...)", NODE_LIST,
                      DEBUG_MODE)
            certlist.append(b'')
            try:
                assert_template(node, tmpl, txlist, certlist, 'n/a')
            except JSONRPCException:
                pass  # Expected
                certlist.pop()

            # Test 14: Truncated final cert
            mark_logs("Truncated final cert (expecting failure...)", NODE_LIST,
                      DEBUG_MODE)
            lastbyte = certlist[-1].pop()
            try:
                assert_template(node, tmpl, txlist, certlist, 'n/a')
            except JSONRPCException:
                pass  # Expected
            certlist[-1].append(lastbyte)

            # Test 15: invalid field element as a commitment tree
            fake_commitment = (b'\xff' * 32)
            fake_commitment_str = binascii.hexlify(fake_commitment)
            assert_template(node, tmpl, txlist, certlist,
                            'invalid-sc-txs-commitment', fake_commitment)

            # Test 16: wrong commitment, the block will be rejected because it is different from the one computed using tx/certs
            rnd_fe = generate_random_field_element_hex()
            fake_commitment = a2b_hex(rnd_fe)
            assert_template(node, tmpl, txlist, certlist,
                            'bad-sc-txs-commitment', fake_commitment)