def test_getdata_message_with_two_blocks(self): cblock1 = CBlock() block1 = Block(cblock1, BlockOrigin.private) block1.cblock = cblock1 cInv1 = CInv() cInv1.type = networking.inv_typemap['Block'] cInv1.hash = cblock1.GetHash() cblock2 = CBlock() block2 = Block(cblock2, BlockOrigin.private) block2.cblock = cblock2 cInv2 = CInv() cInv2.type = networking.inv_typemap['Block'] cInv2.hash = cblock2.GetHash() message = messages.msg_getdata() message.inv = [cInv1, cInv2] self.chain.blocks = { cblock1.GetHash(): block1, cblock2.GetHash(): block2 } self.networking.getdata_message(self.public_connection1, message) self.assertTrue(self.public_connection1.send.called) self.assertEqual(self.public_connection1.send.call_count, 2)
def test(self): """ Gerenal test. """ # Creates a new chain chain = Chain() # Puts some blocks into the chain block_1 = Block("apple", "0") chain.add(block_1) block_1.mine() block_2 = Block("banana", block_1.hash) chain.add(block_2) block_2.mine() block_3 = Block("cat", block_2.hash) chain.add(block_3) # Check if the chain is "not valid" if the last block is not mined self.assertFalse(chain.is_valid) block_3.mine() # Checks if the chain is valid self.assertTrue(chain.is_valid)
def test_adopt_same_height(self): private_tip = Block(CBlock(), None) private_tip.height = 2 public_tip = Block(CBlock(), None) public_tip.height = 2 with self.assertRaisesRegexp(ActionException, "public tip.*must > then private tip.*adopt.*"): self.executor.execute(Action.adopt, private_tip, public_tip)
def test_override_same_height(self): private_tip = Block(CBlock(), None) private_tip.height = 2 public_tip = Block(CBlock(), None) public_tip.height = 2 with self.assertRaisesRegexp(ActionException, "private tip.*must > then public tip.*override.*"): self.executor.execute(Action.override, private_tip, public_tip)
def test_match_lead_public(self): private_tip = Block(CBlock(), None) private_tip.height = 1 public_tip = Block(CBlock(), None) public_tip.height = 2 with self.assertRaisesRegexp(ActionException, "private tip.*must >= then public tip.*match.*"): self.executor.execute(Action.match, private_tip, public_tip)
def test_block(self): args = (0, "0", int(time.time()), "test") nonce = 0 target = "f" * 64 hash = Block.calculate_hash(*args, nonce, target) b = Block(*args, nonce=nonce, target=target, hash=hash) self.assertSerializable(Block, b, globals()) self.assertTrue(b.is_valid()) b = Block(*args, nonce=nonce, target=target, hash="aaa") self.assertFalse(b.is_valid())
def test_send_inv_public_blocks(self): block1 = Block(CBlock(), BlockOrigin.public) block1.cached_hash = 'hash1' block2 = Block(CBlock(), BlockOrigin.public) block2.cached_hash = 'hash2' self.networking.send_inv([block1, block2]) self.assertFalse(self.public_connection1.send.called) self.assertFalse(self.public_connection2.send.called) self.assertTrue(self.private_connection.send.called) inv = self.private_connection.send.call_args[0][1].inv self.assertEqual(len(inv), 2)
def test_insert_block_initializing_false(self): prevBlock = Block(CBlock(), BlockOrigin.private) prevBlock.cached_hash = 'hash2' prevBlock.height = 45 block = Block(CBlock(), BlockOrigin.private) block.cached_hash = 'hash1' self.chain.tips = [prevBlock] self.chain.initializing = False self.chain.insert_block(prevBlock, block) retrieved_block = self.chain.tips[0] self.assertEqual(retrieved_block, block) self.assertEqual(retrieved_block.transfer_allowed, False)
def mine(self): """ Looks in redis for transactions and mines them to find the answer to the puzzle """ print("Mining") prev_hash = self.r.get(PREV_HASH_KEY) if prev_hash: prev_hash = prev_hash.decode('utf-8') block = Block(prev_hash) # wait to fill the block with transactions while not block.full(): # in between mining if self.stop_mining(): print("Someone mined the coins") l = len(block.transactions) left = TRANSACTIONS_IN_BLOCK - l for _ in range(left): self.r.blpop(TRANSACTION_QUEUE_KEY) return None print("Searching for transactions to fill the block") # blocking pop from transaction key transaction = Transaction.from_redis( self.r, json.loads( self.r.blpop(TRANSACTION_QUEUE_KEY)[1].decode('utf-8'))) print("found a transaction, adding it to block") block.add_transaction(transaction) # create a new transaction that creates a lazycoin and gives it to the user print("Block is full, now add a create transaction") print("Prev hash = ", prev_hash) create = Transaction( prev_hash=prev_hash, transaction_type='CREATE', sender=self.user.pub, receiver=self.user.pub, ) # sign this transaction and add the signature to the transaction print("signing transaction") msg, sign = self.user.sign(create) create.add_signature(sign) print("adding transaction") block.add_transaction(create) print("finding nonce") nonce = self.solve_puzzle(block) block.add_nonce(nonce) print("block done") if self.stop_mining(): print("stopping mining") return None return block
def init(): # 删除旧文件 if os.path.isfile(STORE_BLC_FILE_PATH): os.remove(STORE_BLC_FILE_PATH) if os.path.isfile(STORE_KEYS_FILE_PATH): os.remove(STORE_KEYS_FILE_PATH) # 打开N服务和B服务 NetworkRouting.get_instance().start_server() FullBlockChain.get_instance().start_server() # 添加创世区块 keys = [UserKey() for i in range(10)] for key in keys: Wallet.get_instance().add_key(key) Miner.get_instance().set_wallet_address(keys[0].get_address()) t = Transaction() for key in keys: t.add_output(TransOutput(Btc("1000"), key.get_address())) block = Block(1) block.add_transaction(t) head_trans = Transaction() head_trans.add_output(TransOutput(Btc(MINING_BTCS), keys[0].get_address())) block.set_head_transaction(head_trans) block.find_randnum() FullBlockChain.get_instance().add_first_block(block) Wallet.get_instance().write_keys_to_file()
def getInitialUser(): private_key = ed25519.Ed25519PrivateKey.from_private_bytes( bytes.fromhex( "1d82897e5881368cac9eb99126cdfca1e0317629dbeaa7280484c5dae81e932b") ) public_key = ed25519.Ed25519PublicKey.from_public_bytes( bytes.fromhex( "75efa6f1fdf1393a5ea815b2b3690293d079df187944f22ec79f3380ef7bd743") ) txns = [ Transaction.build_signed_txn( "75efa6f1fdf1393a5ea815b2b3690293d079df187944f22ec79f3380ef7bd743", [], [ OutFlow( 10000, "75efa6f1fdf1393a5ea815b2b3690293d079df187944f22ec79f3380ef7bd743" ) ], "1d82897e5881368cac9eb99126cdfca1e0317629dbeaa7280484c5dae81e932b") ] # Note that we need two hexadecimal digits for the bytes.fromhex( str ) method to work, # hence we include two zeros block_obj = Block("00", txns, 0) success = False while not success: magic_num = os.urandom(32).hex() block_obj.magic_num = magic_num if int(block_obj.get_hash(), 16) & 0xFFFF == 0xCCCC: success = True print(json.dumps(block_obj.serialize()))
def __mining(self) -> Optional[Block]: """挖矿""" trans_list = self.__get_mining_trans() with FullBlockChain.safe_use_blockchain() as blc: block = Block(blc.get_height() + 1, blc.get_top_hash()) # 计算总交易费 fee = Btc("0") for trans in trans_list: fee += blc.compute_transaction_fee(trans) block.add_transaction(trans) # 添加交易到block中 # 加上矿工奖励 fee += block.get_now_ming_btcs() # 构造创块交易 head_trans = Transaction() head_trans.add_output(TransOutput(address=self.address, btcs=fee)) block.set_head_transaction(head_trans) # 正式开始挖矿 while not block.veri_hash(): if self.mine_flag: block.randnum += MINING_ADD_NUM block.timestap = time.time() else: # 中止挖矿(失败了) self.add_trans(*trans_list) # 把交易放回交易池 return None return block
def __init__(self) -> None: self.trans_cache = MyQueue() # 交易池 self.trans_num = MAX_USER_TRANSACTION_NUMBER # 一个区块打包多少个交易 self.address = "" # 获取收益的地址 self.server_flag = True self.mine_flag = True self.trans_later = Transaction() self.block_later = Block()
def test_insert_block(self): prevBlock = Block(CBlock(), BlockOrigin.private) prevBlock.cached_hash = 'hash2' prevBlock.height = 45 block = Block(CBlock(), BlockOrigin.private) block.cached_hash = 'hash1' self.chain.tips = [prevBlock] self.chain.insert_block(prevBlock, block) self.assertFalse(prevBlock in self.chain.tips) self.assertEqual(len(self.chain.tips), 1) retrieved_block = self.chain.tips[0] self.assertEqual(retrieved_block, block) self.assertEqual(retrieved_block.prevBlock, prevBlock) self.assertEqual(retrieved_block.height, 46)
def test_getheaders_message_no_block_found(self, mock): message = messages.msg_getheaders() block1 = Block('cblock_header1', BlockOrigin.private) block1.cblock = CBlock(nNonce=1) block2 = Block('cblock_header2', BlockOrigin.private) block2.cblock = CBlock(nNonce=2) mock.return_value = [block1, block2] self.networking.getheaders_message(self.private_connection, message) self.assertTrue(self.private_connection.send.called) self.assertEqual( len(self.private_connection.send.call_args[0][1].headers), 2) self.assertEqual( self.private_connection.send.call_args[0][1].headers[0], block1.cblock) self.assertEqual( self.private_connection.send.call_args[0][1].headers[1], block2.cblock)
def test_headers_message_known_blocks(self): cblock1 = CBlock(nNonce=1) block1 = Block(cblock1, None) cblock2 = CBlock(nNonce=2) block2 = Block(cblock2, None) self.chain.blocks = {block1.hash(): block1, block2.hash(): block2} self.networking.request_blocks = MagicMock() message = messages.msg_headers() message.headers = [cblock1.get_header(), cblock2.get_header()] self.networking.headers_message(self.public_connection1, message) self.assertFalse(self.public_connection1.send.called) self.assertFalse(self.chain.process_header.called) self.assertFalse(self.private_connection.send.called) self.assertTrue(self.networking.request_blocks.called) self.assertEqual(len(self.networking.request_blocks.call_args[0][1]), 0)
def test_block_message(self): message = messages.msg_block() cblock = CBlock() message.block = cblock block = Block(None, BlockOrigin.private) block.cached_hash = message.block.GetHash() self.chain.blocks = {block.hash(): block} self.networking.block_message(self.private_connection, message) self.assertEqual(self.chain.blocks[block.hash()].cblock, cblock)
def test_send_inv_blocks(self): block1 = Block(CBlock(), BlockOrigin.public) block1.cached_hash = 'hash1' block2 = Block(CBlock(), BlockOrigin.public) block2.cached_hash = 'hash2' block3 = Block(CBlock(), BlockOrigin.public) block3.cached_hash = 'hash3' block4 = Block(CBlock(), BlockOrigin.private) block4.cached_hash = 'hash4' block5 = Block(CBlock(), BlockOrigin.private) block5.cached_hash = 'hash5' self.networking.send_inv([block1, block2, block3, block4, block5]) self.assertTrue(self.private_connection.send.called) inv = self.private_connection.send.call_args[0][1].inv self.assertEqual(len(inv), 3) self.assertTrue(self.public_connection1.send.called) self.assertTrue(self.public_connection2.send.called) self.assertEqual(len(self.public_connection2.send.call_args[0][1].inv), 2)
def test_block_message_two_times(self): message = messages.msg_block() cblock1 = CBlock(nNonce=1) cblock2 = CBlock(nNonce=2) message.block = cblock1 block = Block(None, BlockOrigin.private) block.cached_hash = message.block.GetHash() self.chain.blocks = {block.hash(): block} self.networking.block_message(self.private_connection, message) message.block = cblock2 self.networking.block_message(self.private_connection, message)
def setUp(self): self.networking = MagicMock() self.executor = Executor(self.networking) self.first_block_chain_b = Block(CBlock(), BlockOrigin.public) self.first_block_chain_b.height = 1 self.first_block_chain_b.prevBlock = test_util.genesis_block self.first_block_chain_b.cached_hash = '1b' self.second_block_chain_b = Block(CBlock(), BlockOrigin.public) self.second_block_chain_b.height = 2 self.second_block_chain_b.prevBlock = self.first_block_chain_b self.second_block_chain_b.cached_hash = '2b' self.first_block_chain_a = Block(CBlock(), BlockOrigin.private) self.first_block_chain_a.height = 1 self.first_block_chain_a.prevBlock = test_util.genesis_block self.first_block_chain_a.cached_hash = '1a' self.second_block_chain_a = Block(CBlock(), BlockOrigin.private) self.second_block_chain_a.height = 2 self.second_block_chain_a.prevBlock = self.first_block_chain_a self.second_block_chain_a.cached_hash = '2a'
def test_block_message_remove_from_blocks_in_flight(self): message = messages.msg_block() cblock = CBlock() message.block = cblock block = Block(None, BlockOrigin.private) block.cached_hash = message.block.GetHash() self.chain.blocks = {block.hash(): block} self.networking.blocks_in_flight = {block.hash(): 'in_flight'} self.networking.block_message(self.private_connection, message) self.assertEqual(len(self.networking.blocks_in_flight), 0)
def test_request_get_headers_very_long_chain(self, mock): first_block = Block(CBlock(), BlockOrigin.public) first_block.prevBlock = None first_block.cached_hash = '0' tmp = first_block for i in range(1, 17): block = Block(CBlock(), BlockOrigin.public) block.prevBlock = tmp block.cached_hash = str(i) tmp = block mock.return_value = tmp headers = chainutil.request_get_headers([MagicMock()], BlockOrigin.public) self.assertEqual(len(headers), 5) self.assertEqual(headers[0], '16') self.assertEqual(headers[1], '15') self.assertEqual(headers[2], '13') self.assertEqual(headers[3], '9') self.assertEqual(headers[4], '1')
def test_adopt_two_blocks_lead_public(self): third_block_chain_b = Block(CBlock(), BlockOrigin.public) third_block_chain_b.height = 3 third_block_chain_b.prevBlock = self.second_block_chain_b third_block_chain_b.cached_hash = '3b' self.executor.execute(Action.adopt, self.first_block_chain_a, third_block_chain_b) self.assertTrue(self.networking.send_inv.called) blocks = [block.hash() for block in self.networking.send_inv.call_args[0][0]] self.assertEqual(len(blocks), 3) self.assertTrue('1b' in blocks) self.assertTrue('2b' in blocks) self.assertTrue('3b' in blocks)
def test_override_two_blocks_lead_private(self): third_block_chain_a = Block(CBlock(), BlockOrigin.private) third_block_chain_a.height = 3 third_block_chain_a.prevBlock = self.second_block_chain_a third_block_chain_a.cached_hash = '3a' self.executor.execute(Action.override, third_block_chain_a, self.first_block_chain_b) self.assertTrue(self.networking.send_inv.called) blocks = [block.hash() for block in self.networking.send_inv.call_args[0][0]] self.assertEqual(len(blocks), 3) self.assertTrue('1a' in blocks) self.assertTrue('2a' in blocks) self.assertTrue('1b' in blocks)
def test_getdata_message_cblock_not_available(self): cblock = CBlock() hash_ = cblock.GetHash() block = Block(cblock, BlockOrigin.private) message = messages.msg_getdata() cInv = CInv() cInv.type = networking.inv_typemap['Block'] cInv.hash = hash_ message.inv = [cInv] self.chain.blocks = {hash_: block} self.networking.deferred_block_requests = {} self.networking.getdata_message(self.public_connection1, message) self.assertFalse(self.public_connection1.called) self.assertIn(hash_, self.networking.deferred_block_requests) self.assertIn(self.public_connection1.host[0], self.networking.deferred_block_requests[hash_])
def test_getdata_message_with_block(self): cblock = CBlock() block = Block(cblock, BlockOrigin.private) block.cblock = cblock message = messages.msg_getdata() cInv = CInv() cInv.type = networking.inv_typemap['Block'] cInv.hash = cblock.GetHash() message.inv = [cInv] self.chain.blocks = {cblock.GetHash(): block} self.networking.getdata_message(self.public_connection1, message) self.assertTrue(self.public_connection1.send.called) self.assertEqual(self.public_connection1.send.call_args[0][0], 'block') self.assertEqual(self.public_connection1.send.call_args[0][1].block, cblock)
def main(): blockchain = Blockchain() database = ["hello", "goodbye", "test", "DATA here", "test2"] num = 0 for data in database: num += 1 blockchain.mine(Block(num, data=data)) for block in blockchain.chain: print(block) print(blockchain.isValid()) # i try to change data in blck number 2 without valid nonce blockchain.chain[2].data = "NEW DATA" blockchain.mine(blockchain.chain[2]) print(blockchain.isValid())
def test_block_message_deferred_requests(self): message = messages.msg_block() cblock = CBlock() hash_ = cblock.GetHash() message.block = cblock block = Block(None, BlockOrigin.private) block.cached_hash = hash_ self.networking.deferred_block_requests = \ {hash_: [self.private_connection.host[0], self.public_connection2.host[0]]} self.networking.send_block = MagicMock() self.networking.block_message(self.public_connection1, message) self.assertEqual(len(self.networking.deferred_block_requests), 0) self.assertEqual(self.networking.send_block.call_count, 2) self.assertEqual(self.networking.send_block.call_args[0][1], cblock)
async def proof_of_work(self): nonce = 0 tx = None while True: h = sha256() difficulty = consensus.get_difficulty(self.chain_mgr.chain.chain) target = consensus.STANDARD_TARGET / difficulty prev_block = self.chain_mgr.chain.chain[-1] if not tx: # Poll transaction updates tx = self.pop_transaction() block = Block( **{ 'index': prev_block.index + 1, 'timestamp': time.time(), 'data': { 'transactions': [tx.__dict__] } if tx else 'mining test', 'prev_hash': prev_block.hash, 'difficulty': difficulty, }) logger.info('Tx: {}'.format(tx)) h.update('{}{}{}'.format(prev_block, block, nonce).encode('utf8')) hash_value = int(h.hexdigest(), 16) logger.info( 'Hashed block{}@ difficulty={} nonce={} result={}'.format( block.index, difficulty, nonce, h.hexdigest())) if hash_value < target: logger.info( 'solution found! {} @ target: {}, index: {}'.format( nonce, target, block.index)) block.nonce = nonce return block await asyncio.sleep(1) # 1h/s nonce += 1
def test_get_best_public_block_hash(self, mock): mock.return_value = Block(core.CoreRegTestParams.GENESIS_BLOCK, BlockOrigin.public) self.functions.get_best_public_block_hash()