Ejemplo n.º 1
0
def block_management():
    global global_best_block, global_blockchain, global_txs, global_utxos, global_difficulty

    while True:
        time.sleep(10)

        try:
            last_mined_time = global_blockchain[-1].timestamp
        except:
            last_mined_time = genesis_epoch

        # Auto mine
        # if 30 seconds has passed since last mining
        if (time.time() - last_mined_time > 30):
            # Mine block
            mined_block = mine_block(global_best_block, account_address)

            if (mined_block.coinbase.reward_address == account_address):
                print('[SUCCESS] You found the nonce for block {}'.format(
                    mined_block.height))

            # Broadcast block to nodes
            mined_block_str = json.dumps(mined_block.toJSON())
            for node in global_nodes:
                # If node['host'] is in black list then continue
                if node['host'] in global_blacklisted_nodes:
                    continue

                try:
                    misocoin_cli('receive_mined_block', [mined_block_str],
                                 **node)

                except:
                    pass
Ejemplo n.º 2
0
def send_raw_tx(tx: str):
    global global_best_block, global_txs, global_utxos

    try:
        # Original tx
        _tx_og = copy.deepcopy(tx)

        # Create new tx from the json dump
        tx = Transaction.fromJSON(json.loads(tx))

        # If is new tx then add it to block
        if tx.txid not in global_txs:
            # Add tx to global best block
            global_best_block, global_txs, global_utxos = mutils.add_tx_to_block(
                tx, global_best_block, global_txs, global_utxos)

            print('[INFO] txid {} added to block {}'.format(
                tx.txid, global_best_block.height))

            # Broadcast transaction to connected nodes
            for node in global_nodes:
                try:
                    misocoin_cli('send_raw_tx', [json.dumps(tx.toJSON())],
                                 **node)
                except Exception as e:
                    pass

        return {'txid': tx.txid}

    except Exception as e:
        return {'error': str(e)}
Ejemplo n.º 3
0
def sync_with_nodes():
    '''
    Syncs blocks with node
    '''
    global global_nodes

    # Init connection
    for node in global_nodes:
        try:
            misocoin_cli('init_connection', [global_host, global_port], **node)
        except:
            pass

    # Checks every 15 seconds
    while True:
        # Checks with nodes, syncs with the one with
        # the longest chain
        longest_node = None
        best_height = len(global_blockchain)

        for node in global_nodes:
            # If node['host'] is in black list then continue
            if node['host'] in global_blacklisted_nodes:
                continue

            try:
                node_best_length = misocoin_cli('get_info', [],
                                                **node)['height']

                if node_best_length > best_height:
                    longest_node = node
                    best_height = node_best_length

            except:
                pass

        # Syncs with that node
        if longest_node is not None:
            latest_block_dict: Dict = misocoin_cli('get_block', [best_height],
                                                   **longest_node)
            latest_block: Block = Block.fromJSON(latest_block_dict)

            # Append to latest blockchain
            add_to_blockchain(latest_block)

        time.sleep(10)
Ejemplo n.º 4
0
#! /usr/bin/env python
import requests
import json
import sys

from functools import reduce
from misocoin.sync import misocoin_cli


if __name__ == "__main__":
    if len(sys.argv) < 2:
        print('Missing method')
        exit(0)

    config = filter(lambda x: x[0] is '-', sys.argv[1:])
    config_kwargs = reduce(lambda x, y: {y.split(
        '=')[0][1:]: y.split('=')[1], **x}, config, {})

    params = list(filter(lambda x: x[0] is not '-', sys.argv[1:]))

    result = misocoin_cli(params[0], params[1:], **config_kwargs)

    print(json.dumps(result))
Ejemplo n.º 5
0
def add_to_blockchain(block: Block):
    """
    Helper function to update the blockchain.    

    Also updates the utxo cache and tx cache
    """
    global global_best_block, global_txs, global_utxos, global_difficulty

    # If we don't have the prev block, get it from our nodes
    if (block.height - 1) not in global_blockchain:
        for node in global_nodes:
            try:
                missing_block_dict: Dict = misocoin_cli(
                    'get_block', [block.height - 1], **node)
                missing_block: Block = Block.fromJSON(missing_block_dict)
                add_to_blockchain(missing_block)
                break
            except:
                pass

    # Check block hashes
    if len(global_blockchain) > 0:
        # Check hashes
        if block.prev_block_hash != global_blockchain[block.height -
                                                      1].block_hash:
            raise Exception('Block previous hash doesn\'t match')

        if not block.mined:
            raise Exception('Block hasn\'t been mined')

    # Add block to node
    if block.height not in global_blockchain:
        global_blockchain[block.height] = block

        # Add coinbase to cache
        if block.coinbase.txid not in global_txs:
            global_txs[block.coinbase.txid] = block.coinbase

        if block.coinbase.txid not in global_utxos:
            global_utxos[block.coinbase.txid] = {}
            global_utxos[block.coinbase.txid][0] = {
                'address': block.coinbase.reward_address,
                'amount': block.coinbase.reward_amount,
                'spent': None
            }

        # Add tx
        for tx in block.transactions:
            if tx.txid not in global_txs:
                # Update utxos
                global_best_block, global_txs, global_utxos = mutils.add_tx_to_block(
                    tx, global_best_block, global_txs, global_utxos)

        # Only ammend global_best_block if the block.height
        # is higher
        if (global_best_block.height < block.height + 1):
            global_best_block = Block(prev_block_hash=block.block_hash,
                                      transactions=[],
                                      height=block.height + 1,
                                      timestamp=int(time.time()),
                                      difficulty=global_difficulty,
                                      nonce=0)

        # Broadcast block
        for node in global_nodes:
            try:
                misocoin_cli('receive_mined_block',
                             [json.dumps(block.toJSON())], **node)
            except:
                pass

        # Auto adjust difficulty ever 10 blocks
        # Should be around 300 seconds after 10 blocks
        last_ten_blocks = []
        for i in range(max(1, global_best_block.height - 10),
                       global_best_block.height - 1):
            if i in global_blockchain:
                last_ten_blocks.append(global_blockchain[i])

        if (len(global_blockchain) % 10 == 0):
            lowest_timestamp = reduce(lambda x, y: min(x, y.timestamp),
                                      last_ten_blocks, int(time.time()))
            highest_timestamp = reduce(lambda x, y: max(x, y.timestamp),
                                       last_ten_blocks, genesis_epoch)

            if (highest_timestamp - lowest_timestamp < 300):
                global_difficulty = min(global_difficulty + 1, 64)

            if (highest_timestamp - lowest_timestamp > 300):
                global_difficulty = max(global_difficulty - 1, 1)

            print(
                '[UPDATE] Difficulty adjusted to {}'.format(global_difficulty))

        print('[INFO] Received mined block {}'.format(block.height))