Example #1
0
    def test_chain_constructor(self):
        test_chain = Chain()

        assert len(test_chain.chain) == 1
        assert type(test_chain.get_latest_block()) == Block
        assert test_chain.get_latest_block().data == 'first Block'
        assert test_chain.get_latest_block().index == 0
Example #2
0
    def test_all_blocks_are_valid(self):
        test_chain = Chain()
        test_chain.add_new_block('Block one')
        test_chain.add_new_block('Block two')

        valid = test_chain.all_blocks_valid()

        assert valid is True
Example #3
0
    def test_changed_data_detected(self):
        test_chain = Chain()
        test_chain.add_new_block('Block one')
        test_chain.add_new_block('Block two')
        test_chain.chain[1].data = 'Block 42'

        valid = test_chain.all_blocks_valid()

        assert valid is False
Example #4
0
    def test_changed_time_stamp_detected(self):
        test_chain = Chain()
        test_chain.add_new_block('Block one')
        test_chain.add_new_block('Block two')
        test_chain.chain[1].time_stamp = '2017-08-14T06:16:23.225877'

        valid = test_chain.all_blocks_valid()

        assert valid is False
Example #5
0
    def test_changed_hash_detected(self):
        test_chain = Chain()
        test_chain.add_new_block('Block one')
        test_chain.add_new_block('Block two')
        test_chain.chain[1].hash = '76af6354wronghash'

        valid = test_chain.all_blocks_valid()

        assert valid is False
Example #6
0
    def test_changed_index_or_deleted_block_detected(self):
        test_chain = Chain()
        test_chain.add_new_block('Block one')
        test_chain.add_new_block('Block two')
        del test_chain.chain[1]

        valid = test_chain.all_blocks_valid()

        assert valid is False
Example #7
0
    def __init__(self, filename: str = 'chain'):
        self.filename = filename
        if os.path.isfile(filename):
            with open(filename, 'r') as file:
                stored_chain = file.read()
                file.close()
            self.chain = Chain.from_json(json.loads(stored_chain))
        else:
            self.chain = Chain()

        self.chain.validate()
Example #8
0
    def test_add_new_block(self):
        test_chain = Chain()
        data = 'New Block'

        test_chain.add_new_block(data)

        assert len(test_chain.chain) == 2
        assert type(test_chain.get_latest_block()) == Block
        assert test_chain.get_previous_block().data == 'first Block'
        assert test_chain.get_latest_block().data == 'New Block'
        assert test_chain.get_previous_block().index == 0
        assert test_chain.get_latest_block().index == 1
Example #9
0
def make_chain():
    chain = Chain()

    sender, recipient = Key(), Key()
    trx = Transaction(sender.address, sender.public_key,
                      recipient.address, "Hi")
    trx.sign(sender.private_key)
    genesis = Node.mine_block(0, 0, [trx])
    chain.add_block(genesis)
    for _ in range(1, 2):
        trx = Transaction(sender.address, sender.public_key,
                          recipient.address, "Hi")
        trx.sign(sender.private_key)
        block = Node.mine_block(chain.height, chain.last_block.hash, [trx])
        chain.add_block(block)
    return chain
Example #10
0
class Peer:
    def __init__(self, filename: str = 'chain'):
        self.filename = filename
        if os.path.isfile(filename):
            with open(filename, 'r') as file:
                stored_chain = file.read()
                file.close()
            self.chain = Chain.from_json(json.loads(stored_chain))
        else:
            self.chain = Chain()

        self.chain.validate()

    def store_data(self, data) -> None:
        self.chain.store_data(data)

    def keep_chain(self, n: int, verbose: bool):
        for _ in tqdm(range(n)):
            self.chain.add_block(verbose)
            with open(self.filename, "w") as file:
                file.write(self.chain.to_json())
                file.close()
def validate_block(block, previous_block):
    """Validate correctness of block by defined rules.

    This module doesn't check if there are transactions since the demo will
    generate blocks without transactions.
    """
    if not previous_block:
        return False

    # Index is incremented by 1
    if block.index != previous_block.index + 1:
        logger.info(
            "Wrong index, block index {}, index of last block {}".format(
                block.index, previous_block.index))
        return False

    # New block references old one
    if block.previous_block != previous_block.hash:
        logger.info(
            ("New block does not reference previous one, block hash"
             " {}, hash of last block {}").format(block.hash,
                                                  previous_block.hash))
        return False

    # Matching versions
    if block.version < CONFIG.version:
        logger.info("Older version, block version {}, chain version {}".format(
            block.version, CONFIG.version))
        return False

    # Timestamp not in the future
    if block.timestamp > int(time()):
        logger.info("Timestamp of the new block is in the future")
        return False

    # Valid signature
    content_to_sign = str.encode(block._get_content_for_signing())
    signature = key_utils.hex_to_bytes(block.signature)
    public_key = key_utils.bytes_to_rsa(block.public_key)
    valid = verify(content_to_sign, signature, public_key)
    if not valid:
        logger.info("Signature is not valid, block must be altered")
        return False

    # Check if all transactions are valid
    admissions, doctors, vaccines = Chain().\
        get_registration_caches_by_blockhash(block.previous_block)
    for transaction in block.transactions:
        if not transaction.validate(admissions, doctors, vaccines):
            logger.info("Block contains invalid transactions")
            return False

    # WONTFIX: Actually, a block should never be empty. However, we leave this
    # check disabled for demo purposes.
    # Block has no transactions
    # if len(block.transactions) == 0:
    #     logger.info("Block does not contain any transaction")
    #     return False

    # Number of transactions exceeds the maximum
    if len(block.transactions) > CONFIG.block_size:
        logger.info(
            "Too many transactions, block has {}, maximum is {}".format(
                len(block.transactions), CONFIG.block_size))
        return False

    # Duplicate transactions
    distinct_transactions = len(set([repr(tx) for tx in block.transactions]))
    if len(block.transactions) > distinct_transactions:
        logger.info("Block contains duplicate transactions")
        return False

    # Block hash valid
    content_to_hash = block.get_content_for_hashing()
    sha = sha256()
    sha.update(content_to_hash.encode("utf-8"))
    if block.hash != sha.hexdigest():
        logger.info("Hash is not valid, block must be altered")
        return False

    return True
Example #12
0
def full_client():
    Chain(init=True)
    full_client = FullClient()
    yield full_client
 def __init__(self, host='127.0.0.1', port=5000):
     self.host = host
     self.port = port
     self._peers = set()
     self._chain = Chain()
class Peer(object):
    def __init__(self, host='127.0.0.1', port=5000):
        self.host = host
        self.port = port
        self._peers = set()
        self._chain = Chain()

    def start(self):
        server = socketserver.ThreadingTCPServer((self.host, self.port),
                                                 _PeerRequestHandler)
        server.peer = self
        try:
            server.serve_forever()
        except KeyboardInterrupt as _:
            server.server_close()

    def connect_to_peer(self, host, port):
        if (host, port) in self._peers:
            return
        self._peers.add((host, port))
        peers = self._request_peers(host, port)
        self._add_peers(json.loads(peers))
        self._request_connection()
        self._broadcast_chain()

    def mine(self, data):
        self._chain.mine(data)
        self._broadcast_chain()

    def replace_chain(self, chain):
        self._chain.replace_chain(chain)

    @property
    def chain(self):
        return self._chain

    @property
    def peers(self):
        return [{'host': host, 'port': port} for (host, port) in self._peers]

    def _add_peers(self, peers):
        for peer in peers:
            host = peer['host']
            port = peer['port']
            if host == self.host and port == self.port:
                continue
            if (host, port) in self._peers:
                continue
            self._peers.add((host, port))

    # Communication

    def _request_connection(self):
        message = {'type': 'CONNECT', 'host': self.host, 'port': self.port}
        return self._broadcast(message)

    def _request_peers(self, host, port):
        message = {'type': 'PEERS', 'host': self.host, 'port': self.port}
        return self._unicast(host, port, message)

    def _broadcast_chain(self):
        message = {'type': 'CHAIN', 'chain': self._chain.to_dict()}
        return self._broadcast(message)

    # Base communication

    def _unicast(self, host, port, message):
        pool = multiprocessing.Pool(1)
        result = pool.apply_async(self._send_message,
                                  args=(host, port, message))
        pool.close()
        pool.join()
        return result.get()

    def _broadcast(self, message):
        results = []
        pool = multiprocessing.Pool(5)
        for (host, port) in self._peers:
            results.append(
                pool.apply_async(self._send_message,
                                 args=(host, port, message)))
        pool.close()
        pool.join()
        return [result.get() for result in results]

    def _send_message(self, host, port, message):
        with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
            s.connect((host, port))
            s.sendall(json.dumps(message).encode('utf-8'))
            response = s.recv(655350, 0)
            return response.decode('utf-8')
def test_chain_is_singleton():
    chain_1 = Chain(load_persisted=False)
    chain_2 = Chain(load_persisted=False)
    assert id(chain_1) == id(chain_2)
def chain():
    chain = Chain(load_persisted=False, init=True)
    genesis = create_initial_block()
    chain.add_block(genesis)
    yield chain
Example #17
0
import os
import json
import time
from flask import Flask
from twitter import Api
from blockchain.chain import Chain

app = Flask(__name__)

USER_ID = 25073877  # This is Donald Trump
CONSUMER_KEY = os.getenv("CONSUMER_KEY", None)
CONSUMER_SECRET = os.getenv("CONSUMER_SECRET", None)
ACCESS_TOKEN = os.getenv("ACCESS_TOKEN", None)
ACCESS_TOKEN_SECRET = os.getenv("ACCESS_TOKEN_SECRET", None)

trump_chain = Chain()


@app.route("/")
def hello():
    return "Hello World!"


@app.route("/check")
def check():
    return json.dumps(get_latest_tweets_sorted())


@app.route("/last")
def get_last_block_data():
    return trump_chain.get_latest_block().data