コード例 #1
0
def test_previous_tx_non_existent():
    """ 
     tests transaction update when a previous transaction does
     not exist 
    """
    # make a synthetic previous transaction
    num_prev_tx_outputs = secrets.randbelow(5) + 1
    previous_tx = make_synthetic_previous_transaction(num_prev_tx_outputs)
    
    #reflect this previous transaction in HeliumDB
    ctr = 0
    for vout in previous_tx["vout"]:
        #pdb.set_trace()
        fragment = {}
        fragment["pkhash"] = vout["ScriptPubKey"][2]
        fragment["spent"] = False 
        fragment["value"] = max(secrets.randbelow(1000000), 10)
        fragment["tx_chain"] =  ""

        txid = previous_tx["transactionid"] + "_" + str(ctr)
        chain.put_transaction( txid, fragment)
        ctr += 1

    # make a transaction consuming some previous transaction outputs
    trx = make_synthetic_transaction(previous_tx)
    trx["vin"][0]["txid"] = "bad previous tx id"
    #update the Helium Chainstate
    assert chain.transaction_update(trx) == False
def make_synthetic_transaction(block):
    """
    makes a synthetic transaction with randomized values
    """

    transaction = {}
    transaction['version'] = hconfig.conf["VERSION_NO"]
    transaction['transactionid'] = rcrypt.make_uuid()
    transaction['locktime'] = 0
    transaction['vin'] = []
    transaction['vout'] = []

    # make public-private key pair for the transaction
    pair = rcrypt.make_ecc_keys()
    tx_keys[transaction["transactionid"]] = pair

    # make vin list
    # genesis block does not have inputs
    if block["height"] > 0:
        num_inputs = secrets.randbelow(3) + 1
        for ctr in range(num_inputs):
            trx = make_synthetic_vin(transaction, ctr)
            if trx == False: break
            transaction["vin"].append(trx)

    # make vout list
    num_outputs = secrets.randbelow(5) + 1
    ctr = 0
    for ctr in range(num_outputs):
        vout = make_synthetic_vout(block, transaction, ctr, pair[1])
        if vout != False: transaction["vout"].append(vout)

    block["tx"].append(transaction)
    hchaindb.transaction_update(transaction)

    return transaction
コード例 #3
0
def add_block(block: "dictionary") -> "bool":
    """
    add_block: adds a block to the blockchain. Receives a block.
    The block attributes are checked for validity and each transaction in the block is
    tested for validity. If there are no errors, the block is written to a file as a 
    sequence of raw bytes. Then the block is added to the blockchain.
    The chainstate database and the blk_index databases are updated.
    returns True if the block is added to the blockchain and False otherwise
    """
    try:
        # validate the received block parameters
        if validate_block(block) == False:
            raise(ValueError("block validation error"))

        # validate the transactions in the block
        # update the chainstate database
     
        for trx in block['tx']:
            # first transaction in the block is a coinbase transaction
            if block["height"] == 0 or block['tx'][0] == trx: zero_inputs = True
            else: zero_inputs = False

            if tx.validate_transaction(trx, zero_inputs) == False: 
                raise(ValueError("transaction validation error"))
                    
            if hchaindb.transaction_update(trx) == False:
                raise(ValueError("chainstate update transaction error"))

        # serialize the block to a file
        if (serialize_block(block) == False):
                raise(ValueError("serialize block error"))

        # add the block to the blockchain in memory
        blockchain.append(block)

        #  update the blk_index
        for transaction in block['tx']:
            blockindex.put_index(transaction["transactionid"], block["height"])

    except Exception as err:
        print(str(err))
        logging.debug('add_block: exception: ' + str(err))
        return False

    return True
def build_chainstate():
    '''
    build the Chainstate database from the blockchain files
    '''
    blockno = 0
    tx_count = 0

    try:
        while True:
            # test whether the block file exists
            block_file = "block" + "_" + str(blockno) + ".dat"
            if os.path.isfile(block_file) == False: break

            # load the block file into a dictionary object
            f = open(block_file, 'rb')
            block = pickle.load(f)

            # process the vout and vin arrays for each block transaction
            for trx in block["tx"]:
                ret = hchaindb.transaction_update(trx)
                tx_count += 1
                if ret == False:
                    raise (
                        ValueError("failed to rebuild chainstate. block no: " +
                                   str(blockno)))

            blockno += 1

    except Exception as err:
        print(str(err))
        return False

    print("transactions processed: " + str(tx_count))
    print("blocks processed: " + str(blockno))

    return True