def test_is_valid_block_jumped_difficulty(last_block, block): jumped_difficulty = 10 block.difficulty = jumped_difficulty block.hash = f'{"0" * jumped_difficulty}111abc' with pytest.raises(Exception, match='The block difficulty must only adjust by 1.'): Block.is_valid_block(last_block, block)
def test_mined_block_difficulty_limits_at_1(): last_block = Block(time.time_ns(), 'test_last_hash', 'test_hash', 'test_data', 1, 0) time.sleep(MINE_RATE / SECONDS) mined_block = Block.mine_block(last_block, 'bar') assert mined_block.difficulty == 1
def test_mine_block(): last_block = Block.genesis_block() data = 'test-data' block = Block.mine_block(last_block, data) assert isinstance(block, Block) assert block.data == data assert block.last_hash == last_block.hash assert hex_to_binary( block.hash)[0:block.difficulty] == '0' * block.difficulty
def mine_block(self, transactions): """ 根据链上的最后一个区块的hash值,生成一个新的block :param transactions: :return: """ lash_hash = self.blocks.get("l").decode() height = self.get_height() b = Block() new_block = b.new_block(transactions, lash_hash, height + 1) return new_block
def test_create_bc(): bc = BlockChain() # 创世区块 coinbase = new_coinbase_tx("7AgP8z7XYyZ2sdnVJ6HCiE5X2reJDf") genesis_block = new_genesis_block(coinbase) bc.add_block(genesis_block) b = Block() # 自定义几个block for i in range(5): transactions = [b'Node1', b"Node2", b"Node3", b"Node4"] last_hash = bc.blocks.get("l").decode() height = bc.get_height() new_block = b.new_block(transactions, last_hash, height + 1) bc.add_block(new_block)
def is_valid_chain(chain): """ Validate the incoming chain. Enforce the following rules of the blockchain: - the chain must start with the genesis block. - blocks must be formatted correctly. """ if chain[0] != Block.genesis_block(): raise Exception('The genesis block must be valid.') for i in range(1, len(chain)): block = chain[i] # Previous block: last_block = chain[i - 1] Block.is_valid_block(last_block, block) Blockchain.is_valid_transaction_chain(chain)
def deserialize_jsonified_chain(jsonified_chain): """ Deserialize a list of serialized blocks into a Blockchain instance. The result will contain a chain list of Block instances. """ blockchain = Blockchain() blockchain.chain = list( map( lambda jsonified_block: Block.deserialize_jsonified_block( jsonified_block), jsonified_chain)) return blockchain
def add_block(self, data): if self.blocks.get('l'): # there we should mark last block hash to create a new block. # in the redis the l is the last block hash value key. last_hash = self.blocks.get('l').decode() b = Block() new_block = b.new_block(data, last_hash) pow = ProofOfWork(new_block, new_block["Nonce"]) if pow.validate(): # self.blocks.append(new_block) self.blocks.set(new_block["Hash"], new_block) self.blocks.set("l", new_block["Hash"]) else: b = Block() new_block = b.new_block(data) pow = ProofOfWork(new_block, new_block["Nonce"]) if pow.validate(): # self.blocks.append(new_block) self.blocks.set(new_block["Hash"], new_block) self.blocks.set("l", new_block["Hash"])
def message(self, pubnub, message_object): print( f'\n-- Channel: {message_object.channel} | Message: {message_object.message}' ) if message_object.channel == CHANNELS['BLOCK']: block = Block.deserialize_jsonified_block(message_object.message) potential_chain = self.blockchain.chain[:] #Making copy of existing chain potential_chain.append(block) try: self.blockchain.replace_chain(potential_chain) self.transaction_pool.clear_blockchain_transactions( self.blockchain) print('\n -- Successfully replaced the local chain.') except Exception as e: print(f'\n -- Did not replace chain: {e}') elif message_object.channel == CHANNELS['TRANSACTION']: transaction = Transaction.from_json(message_object.message) self.transaction_pool.set_transaction(transaction) print('\n -- Set the new transaction in the transaction pool.')
#!/usr/bin/env python # -*- coding:utf-8 -*- """ This Document is Created by At 2018/7/9 """ from consensus.proof_of_work import ProofOfWork from core.blockchain.block import Block if __name__ == '__main__': b = Block() genesis_block = b.new_block("Magic test", "") pow = ProofOfWork(genesis_block) pow.run()
def add_block(): b = Block() b.new_block("Magic", "") block = b.block return json.dumps(block)
def add_block(self, data): self.chain.append(Block.mine_block(self.chain[-1], data))
def test_genesis(): genesis = Block.genesis_block() assert isinstance(genesis, Block) for key, value in GENESIS_DATA.items(): getattr(genesis, key) == value
def test_increased_difficulty_mined_block(): last_block = Block.mine_block(Block.genesis_block(), 'foo') mined_block = Block.mine_block(last_block, 'bar') assert mined_block.difficulty == last_block.difficulty + 1
def __init__(self): self.chain = [Block.genesis_block()]
def test_decreased_difficulty_mined_block(): last_block = Block.mine_block(Block.genesis_block(), 'foo') time.sleep(MINE_RATE / SECONDS) mined_block = Block.mine_block(last_block, 'bar') assert mined_block.difficulty == last_block.difficulty - 1
def test_is_valid_block_bad_block_hash(last_block, block): block.hash = '000000000000000012abbbccccbc' with pytest.raises(Exception, match='The block hash must be correct.'): Block.is_valid_block(last_block, block)
def test_invalid_block_bad_proof_of_work(last_block, block): block.hash = 'fff' with pytest.raises(Exception, match='The proof of requirement was not met.'): Block.is_valid_block(last_block, block)
def last_block(): return Block.genesis_block()
def test_is_valid_block_bad_last_hash(last_block, block): block.last_hash = 'evil_last_hash' with pytest.raises(Exception, match='last_hash must be correct'): Block.is_valid_block(last_block, block)
def test_is_valid_block(last_block, block): Block.is_valid_block(last_block, block)
def block(last_block): return Block.mine_block(last_block, 'test_data')