def test_is_valid_transaction_chain_duplicate_transactions(blockchain_three_blocks):
    transaction = Transaction(Wallet(), 'recipient', 1).to_json()

    blockchain_three_blocks.add_block([transaction, transaction])

    with pytest.raises(Exception, match='is not unique'):
        Blockchain.is_valid_transaction_chain(blockchain_three_blocks.chain)
def test_is_valid_transaction_chain_bad_transaction(blockchain_three_blocks):
    bad_transaction = Transaction(Wallet(), 'recipient', 1)
    bad_transaction.input['signature'] = Wallet().sign(bad_transaction.output)
    blockchain_three_blocks.add_block([bad_transaction.to_json()])

    # No exception match, in case does any of the transaction is corrupted
    with pytest.raises(Exception):
        Blockchain.is_valid_transaction_chain(blockchain_three_blocks.chain)
def test_is_valid_transaction_chain_multiple_rewards(blockchain_three_blocks):
    reward_1 = Transaction.reward_transaction(Wallet()).to_json()
    reward_2 = Transaction.reward_transaction(Wallet()).to_json()

    blockchain_three_blocks.add_block([reward_1, reward_2])

    with pytest.raises(Exception, match='one mining reward per block'):
        Blockchain.is_valid_transaction_chain(blockchain_three_blocks.chain)
def test_is_valid_transaction_chain_bad_historic_balance(blockchain_three_blocks):
    wallet = Wallet()
    bad_transaction = Transaction(wallet, 'recipient', 1)
    bad_transaction.output[wallet.address] = 9000
    bad_transaction.input['amount'] = 9001
    bad_transaction.input['signature'] = wallet.sign(bad_transaction.output)

    blockchain_three_blocks.add_block([bad_transaction.to_json()])

    with pytest.raises(Exception, match='has an invalid input amount'):
        Blockchain.is_valid_transaction_chain(blockchain_three_blocks.chain)
def test_clear_blockchain_transaction():
    transaction_pool = TransactionPool()
    transaction_1 = Transaction(Wallet(), 'recipient', 1)
    transaction_2 = Transaction(Wallet(), 'recipient', 2)

    transaction_pool.set_transaction(transaction_1)
    transaction_pool.set_transaction(transaction_2)

    blockchain = Blockchain()
    blockchain.add_block([transaction_1.to_json(), transaction_2.to_json()])

    assert transaction_1.id in transaction_pool.transaction_map
    assert transaction_2.id in transaction_pool.transaction_map

    transaction_pool.clear_blockchain_transactions(blockchain)

    assert not transaction_1.id in transaction_pool.transaction_map
    assert not transaction_2.id in transaction_pool.transaction_map
示例#6
0
def test_calulate_balance():
    blockchain = Blockchain()
    wallet = Wallet()

    assert Wallet.calculate_balance(blockchain,
                                    wallet.address) == STARTING_BALANCE

    amount = 50
    transaction = Transaction(wallet, 'recipient', amount)
    blockchain.add_block([transaction.to_json()])

    assert Wallet.calculate_balance(blockchain, wallet.address) == \
        STARTING_BALANCE - amount

    received_amount_1 = 25
    received_transaction_1 = Transaction(Wallet(), wallet.address,
                                         received_amount_1)

    received_amount_2 = 123
    received_transaction_2 = Transaction(Wallet(), wallet.address,
                                         received_amount_2)

    blockchain.add_block(
        [received_transaction_1.to_json(),
         received_transaction_2.to_json()])

    assert Wallet.calculate_balance(blockchain, wallet.address) == \
        STARTING_BALANCE - amount + received_amount_1 + received_amount_2
示例#7
0
import os
import random
import requests

from flask import Flask, jsonify, request
from flask_cors import CORS

from backend.models.blockchain import Blockchain
from backend.models.wallet import Wallet
from backend.models.transaction import Transaction
from backend.models.transaction_pool import TransactionPool
from backend.pubsub import PubSub

app = Flask(__name__)
CORS(app, resources={r'/*': {'origins': 'http://*****:*****@app.route('/')
def route_default():
    return 'Welcome to the blockchain ;)'


@app.route('/blockchain')
def route_blockchain():
    return jsonify(blockchain.to_json())

示例#8
0
from backend.routes.blueprints import WALLET, BLOCKCHAIN, TRANSACTION
from backend.config import PORT, ROOT_PORT

app = Flask(__name__)


@app.route('/')
def route_default():
    return 'Welcome to the blockchain ;)'


app.register_blueprint(BLOCKCHAIN, url_prefix="/blockchain")
app.register_blueprint(TRANSACTION, url_prefix="/transactions")
app.register_blueprint(WALLET, url_prefix="/wallet")

CORS(app, resources={r'/*': {'origins': 'http://localhost:3001'}})

if os.environ.get('PEER') == 'True':
    PORT = random.randint(5001, 6000)

    result = requests.get(f'http://localhost:{ROOT_PORT}/blockchain')
    result_blockchain = Blockchain.from_json(result.json())

    try:
        Blockchain.replace_chain(result_blockchain.chain)
        print('\n -- Succesfully synchronized the local chain')
    except Exception as e:
        print(f'\n --Error synchronizing: {e}')

app.run(port=PORT)
示例#9
0
import os
import random

from flask import Blueprint, jsonify, request

from backend.models.blockchain import Blockchain
from backend.models.wallet import Wallet
from backend.models.transaction import Transaction
from backend.models.transaction_pool import TransactionPool
from backend.pubsub import PubSub

blockchain = Blockchain()
wallet = Wallet(blockchain)
transaction_pool = TransactionPool()
pubsub = PubSub(blockchain, transaction_pool)

BLOCKCHAIN = Blueprint('BLOCKCHAIN', __name__)


@BLOCKCHAIN.route('/', methods=['GET'])
def default_blockchain_route():
    return jsonify(blockchain.to_json())


@BLOCKCHAIN.route('/range', methods=['GET'])
# http://localhost:5000/blockchain/range?start=3&&end=6
def route_blockchain_range():
    start = int(request.args.get('start'))
    end = int(request.args.get('end'))

    return jsonify(blockchain.to_json()[::-1][start:end])
示例#10
0
def test_add_block():
    blockchain = Blockchain()
    data = 'test_data'
    blockchain.add_block(data)

    assert blockchain.chain[-1].data == data
示例#11
0
import time
from backend.models.blockchain import Blockchain
from backend.config import SECONDS

blockchain = Blockchain()

times = []

for i in range(1000):
    start_time = time.time_ns()
    blockchain.add_block(i)
    end_time = time.time_ns()

    time_to_mine = (end_time - start_time) / SECONDS
    times.append(time_to_mine)

    average_time = sum(times) / len(times)

    print(f'Block number: {i+1}')
    print(f'New block difficulty: {blockchain.chain[-1].difficulty}')
    print(f'Time to mine new block: {time_to_mine}s')
    print(f'Average time to add blocks: {average_time}s\n')
示例#12
0
def test_blockchain_instance():
    blockchain = Blockchain()

    assert blockchain.chain[0].hash == GENESIS_DATA['hash']
示例#13
0
def blockchain_three_blocks():
    blockchain = Blockchain()
    for i in range(3):
        blockchain.add_block([Transaction(Wallet(), 'recipient', i).to_json()])
    return blockchain
示例#14
0
from flask import Blueprint, jsonify, request

from backend.models.blockchain import Blockchain
from backend.models.transaction import Transaction
from backend.models.transaction_pool import TransactionPool
from backend.models.wallet import Wallet
from backend.pubsub import PubSub

blockchain = Blockchain()
wallet = Wallet(blockchain)
transaction_pool = TransactionPool()
pubsub = PubSub(blockchain, transaction_pool)

WALLET = Blueprint('WALLET', __name__)


@WALLET.route('/info', methods=['GET'])
def route_wallet_info():
    return jsonify({'address': wallet.address, 'balance': wallet.balance})


@WALLET.route('/transact', methods=['POST'])
def route_wallet_transact():
    transaction_data = request.get_json()
    transaction = transaction_pool.existing_transaction(wallet.address)

    if transaction:
        transaction.update(wallet, transaction_data['recipient'],
                           transaction_data['amount'])
    else:
        transaction = Transaction(wallet, transaction_data['recipient'],
示例#15
0
def test_is_valid_chain(blockchain_three_blocks):
    # Compare two different instances of the same class in python, it will results as False.
    # E.g foo = Block.genesis(), bar = Block.genesis(), foo == bar => False
    Blockchain.is_valid_chain(blockchain_three_blocks.chain)
示例#16
0
def test_valid_transaction_chain(blockchain_three_blocks):
    Blockchain.is_valid_transaction_chain(blockchain_three_blocks.chain)
示例#17
0
def test_replace_chain_bad_chain(blockchain_three_blocks):
    blockchain = Blockchain()
    blockchain_three_blocks.chain[1].hash = 'evil_hash'

    with pytest.raises(Exception, match= 'The incomming chain is invalid'):
        blockchain.replace_chain(blockchain_three_blocks.chain)
示例#18
0
def test_replace_chain_not_longer(blockchain_three_blocks):
    blockchain = Blockchain()

    with pytest.raises(Exception, match= 'The incoming chain must be longer'):
        blockchain_three_blocks.replace_chain(blockchain.chain)
示例#19
0
def test_replace_chain(blockchain_three_blocks):
    blockchain = Blockchain()
    blockchain.replace_chain(blockchain_three_blocks.chain)

    assert blockchain.chain == blockchain_three_blocks.chain
示例#20
0
def test_is_valid_chain_bad_genesis(blockchain_three_blocks):
    blockchain_three_blocks.chain[0].hash = 'evil_hash'

    with pytest.raises(Exception, match='genesis block must be valid'):
        Blockchain.is_valid_chain(blockchain_three_blocks.chain)