def mine_forever(): while True: my_address = init_wallet()[2] block = assemble_and_solve_block(my_address) if block: connect_block(block) save_to_disk()
def handle(self): data = read_all_from_socket(self.request) peer_hostname = self.request.getpeername()[0] peer_hostnames.add(peer_hostname) if hasattr(data, 'handle') and isinstance(data.handle, Callable): data.handle(self.request, peer_hostname) elif isinstance(data, Transaction): logger.info(f'received txn {data.id} for peer {peer_hostname}') mempool.add_txn_to_mempool(data) elif isinstance(data, block.Block): logger.info(f'received block {data.id} from peer {peer_hostname}') connect_block(data)
def test_dependent_txns_in_single_block(): set_active_chain([]) mempool.clear() assert connect_block(chain1[0]) == ACTIVE_CHAIN_IDX assert connect_block(chain1[1]) == ACTIVE_CHAIN_IDX assert len(get_active_chain()) == 2 assert len(utxo_set) == 2 utxo1 = utxo_set[list(utxo_set.keys())[0]] txout1 = TxOut(value=901, pubkey=utxo1.pubkey) txin1 = make_txin(signing_key, utxo1.outpoint, txout1) txn1 = Transaction(txins=[txin1], txouts=[txout1], locktime=0) # Create a transaction that is depend on the yet-unconfirmed transaction above txout2 = TxOut(value=9001, pubkey=txout1.pubkey) txin2 = make_txin(signing_key, OutPoint(txn1.id, 0), txout2) txn2 = Transaction(txins=[txin2], txouts=[txout2], locktime=0) # assert that we don't accept this txn -- too early to spend the coinbase with pytest.raises(TxnValidationError) as excinfo: validate_txn(txn2) assert 'Spend value is more than available' in str(excinfo) connect_block(chain1[2]) add_txn_to_mempool(txn1) assert txn1.id in mempool # In txn2, we're attemping to spend more than is available (9001 vs. 901). assert not add_txn_to_mempool(txn2) with pytest.raises(TxnValidationError) as excinfo: validate_txn(txn2) assert 'Spend value is more than available' in str(excinfo.value) # Recreate the transaction with an acceptable value txout2 = TxOut(value=901, pubkey=txout1.pubkey) txin2 = make_txin(signing_key, OutPoint(txn1.id, 0), txout2) txn2 = Transaction(txins=[txin2], txouts=[txout2], locktime=0) add_txn_to_mempool(txn2) assert txn2.id in mempool
def handle(self, sock, peer_hostname): logger.info(f'[p2p] recv inv from {peer_hostname}') new_blocks = [b for b in self.blocks if not locate_block(b.id)[0]] if not new_blocks: logger.info('[p2p] initial block download complete') ibd_done.set() return for block in new_blocks: connect_block(block) new_tip_id = get_active_chain()[-1].id logger.info(f'[p2p] continuing initial block download at {new_tip_id}') with chain_lock: # Recursive call to continue the initial block sync send_to_peer(GetBlocksMsg(new_tip_id))
def test_reorg(): set_active_chain([]) for block in chain1: assert connect_block(block) == ACTIVE_CHAIN_IDX set_side_branches([]) mempool.clear() utxo_set.clear() _add_to_utxo_for_chain(get_active_chain()) def assert_no_change(): assert get_active_chain() == chain1 assert mempool == {} assert [k.txid[:6] for k in utxo_set] == ['804da2', 'd961d7', '54b38d'] assert len(utxo_set) == 3 # No reorg necessary when side branches are empty assert not reorg_if_necessary() print(f'{[b.id for b in chain1]}') from mini_core.merkle_trees import get_merkle_root_of_txns print(f'{[get_merkle_root_of_txns(b.txns).value for b in chain2]}') # No reorg necessary when side branch is shorter than the main chain for block in chain2[1:2]: assert connect_block(block) == 1 assert not reorg_if_necessary() assert get_side_branches() == [chain2[1:2]] assert_no_change() # No reorg necessary when side branch is as long as the main chain. assert connect_block(chain2[2]) == 1 assert not reorg_if_necessary() assert get_side_branches() == [chain2[1:3]] assert_no_change() # No reorg necessary when side branch is a longer but invalid chain # Block doesn't connect to anything because it's invalid assert connect_block(chain3_faulty[3]) is None assert not reorg_if_necessary() # No change in side branches for an invalid block. assert get_side_branches() == [chain2[1:3]] assert_no_change() # Reorg necessary when a side branch is longer than the main chain assert connect_block(chain2[3]) == 1 assert connect_block(chain2[4]) == 1 # Chain1 was reorged into get_side_branches(). assert [len(c) for c in get_side_branches()] == [2] assert [b.id for b in get_side_branches()[0]] == [b.id for b in chain1[1:]] assert get_side_branches() == [chain1[1:]] assert mempool == {} print(f'{[tx.txid[:6] for tx in utxo_set]}') assert [k.txid[:6] for k in utxo_set] == ['804da2', 'd961d7', '54b38d', '48f7f5', 'ac4700']