def test_move_to_block(self): b1 = Block(1, GENESIS.block_id, [Transaction(1, 'a', 1)], 1) b2 = Block(2, GENESIS.block_id, [Transaction(2, 'a', 2)], 2) b3 = Block(3, b2.block_id, [Transaction(3, 'a', 3)], 3) b4 = Block(4, b3.block_id, [Transaction(4, 'a', 4)], 4) b5 = Block(5, b2.block_id, [Transaction(5, 'a', 5)], 5) b6 = Block(6, b4.block_id, [Transaction(6, 'a', 6)], 6) self.node.blocktree.add_block(b1) self.node.blocktree.add_block(b2) self.node.blocktree.add_block(b3) self.node.blocktree.add_block(b4) self.node.blocktree.add_block(b5) self.node.blocktree.add_block(b6) self.node.blocktree.head_block = b4 old = self.node.blocktree.head_block # should both have no effect self.node.move_to_block(b3) self.node.move_to_block(b4) assert self.node.blocktree.head_block == old self.node.move_to_block(b6) assert self.node.blocktree.head_block == b6 self.node.broadcast = MagicMock() self.node.move_to_block(b1) assert self.node.broadcast.called assert self.node.blocktree.head_block == b1
def scenario6(node): """Quick node broadcasts a transaction. This scenario assumes a healthy state i.e one quick node and the others are slow. Args: node (Node): Node calling this method """ logging.debug('start test scenario 6') if node.id == 0: # create a Transaction and broadcast it txn = Transaction(0, 'command1', 1) node.broadcast(txn, 'TXN')
def test_pam(self): """Test receipt of a PaxosMessage. """ self.node.receive_paxos_message = MagicMock() txn1 = Transaction(0, 'command1', 1) txn2 = Transaction(0, 'command2', 2) block = Block(0, 0, [txn1, txn2], 1) txn3 = Transaction(0, 'command3', 3) block2 = Block(1, 1, [txn1, txn3], 2) pam = PaxosMessage('TRY', 2) pam.new_block = block.block_id pam.last_committed_block = block2.block_id s = pam.serialize() self.proto.stringReceived(s) self.assertTrue(self.node.receive_paxos_message.called) obj = self.node.receive_paxos_message.call_args[0][0] self.assertEqual(type(obj), PaxosMessage) self.assertEqual(obj.new_block, block.block_id) self.assertEqual(obj.last_committed_block, block2.block_id)
def scenario2(node): """Start the paxos algorithm by bringing a Transaction in circulation. A node broadcasts the transaction. This scenario assumes a healthy state i.e one quick node and the others are slow. Args: node (Node): Node calling this method """ logging.debug('start test scenario 2') if node.id == 2: # create a Transaction and broadcast it txn = Transaction(2, 'command1', 1) node.broadcast(txn, 'TXN')
def scenario5(node): """Multiple nodes broadcast a transaction. This scenario assumes a healthy state i.e one quick node and the others are slow. Args: node (Node): Node calling this method """ logging.debug('start test scenario 5') if node.id == 2: # create a Transaction and broadcast it txn = Transaction(2, 'command1', 1) node.broadcast(txn, 'TXN') elif node.id == 1: # create a Transaction and broadcast it txn = Transaction(1, 'command2', 2) node.broadcast(txn, 'TXN') # create another Transaction and broadcast it txn3 = Transaction(1, 'command3', 3) node.broadcast(txn, 'TXN') deferLater(reactor, 1, node.broadcast, txn3, 'TXN')
def scenario8(node): """Unhealthy state: q = 1 and m > 1. Quick node will create a block which demotes other medium nodes. Thus we are back in a healthy state again. Args: node (Node): Node calling this method """ logging.debug('start test scenario 8') if node.id == 0: # quick node node.state = 0 elif node.id == 1: # medium node node.state = 1 elif node.id == 2: # medium node node.state = 1 # create a Transaction and broadcast it txn = Transaction(2, 'command1', 1) deferLater(reactor, 0.1, node.broadcast, txn, 'TXN')
def scenario7(node): """Unhealthy state: q = 0 and m = 1. Medium node will create a block and promote itself. Thus we are in a healthy state again. Because the node is quick it will directly start a paxos instance. Args: node (Node): Node calling this method """ logging.debug('start test scenario 7') if node.id == 0: # medium node node.state = 1 elif node.id == 1: # slow node node.state = 2 elif node.id == 2: # slow node node.state = 2 # create a Transaction and broadcast it txn = Transaction(2, 'command1', 1) deferLater(reactor, 0.1, node.broadcast, txn, 'TXN')
def scenario32(node): """Test a partition. Args: node (Node): Node calling this method """ # class patching Node.broadcast = IntegrationScenarios.broadcast Node.partitioned = True logging.debug('start test scenario 32') # partition will be resolved after given time deferLater(reactor, 4, IntegrationScenarios.resolvePartition) if node.id == 2: # create a Transaction and broadcast it txn = Transaction(2, 'command1', 1) deferLater(reactor, 0.1, node.broadcast, txn, 'TXN') # create a Transaction and broadcast it txn2 = Transaction(2, 'command2', 2) deferLater(reactor, 2, node.broadcast, txn2, 'TXN') # create a Transaction and broadcast it txn3 = Transaction(2, 'command3', 3) deferLater(reactor, 6, node.broadcast, txn3, 'TXN') # create a Transaction and broadcast it txn4 = Transaction(2, 'command4', 4) deferLater(reactor, 8, node.broadcast, txn4, 'TXN') elif node.id == 4: # create a Transaction and broadcast it txn5 = Transaction(4, 'command5', 5) deferLater(reactor, 0.1, node.broadcast, txn5, 'TXN') # create a Transaction and broadcast it txn6 = Transaction(4, 'command6', 6) deferLater(reactor, 2, node.broadcast, txn6, 'TXN')
def test_create_block(self): # create a blocktree and add blocks to it b1 = Block(1, GENESIS.block_id, [Transaction(1, 'a', 1)], 1) b2 = Block(2, GENESIS.block_id, [Transaction(1, 'a', 2)], 2) b3 = Block(3, b2.block_id, [Transaction(1, 'a', 3)], 3) b4 = Block(4, b3.block_id, [Transaction(1, 'a', 4)], 4) b5 = Block(5, b2.block_id, [Transaction(1, 'a', 5)], 5) self.node.blocktree.add_block(b1) self.node.blocktree.add_block(b2) self.node.blocktree.add_block(b3) self.node.blocktree.add_block(b4) self.node.blocktree.add_block(b5) self.node.blocktree.head_block = b4 self.node.new_txs = [Transaction(1, 'a', 6)] c = self.node.create_block() assert len(self.node.new_txs) == 0 assert self.node.blocktree.nodes.get(c.block_id) == c
def test_reach_genesis_block(self): b1 = Block(1, GENESIS.block_id, [Transaction(1, 'a', 1)], 1) b2 = Block(2, GENESIS.block_id, [Transaction(1, 'a', 2)], 2) b3 = Block(3, b2.block_id, [Transaction(1, 'a', 3)], 3) b4 = Block(4, b3.block_id, [Transaction(1, 'a', 4)], 4) b5 = Block(5, b2.block_id, [Transaction(1, 'a', 5)], 5) self.node.blocktree.add_block(b1) self.node.blocktree.add_block(b2) self.node.blocktree.add_block(b3) self.node.blocktree.add_block(b4) self.node.blocktree.add_block(b5) assert self.node.reach_genesis_block(b5) b = Block(1, 1234, [Transaction(1, 'a', 6)], 6) self.node.broadcast = MagicMock() self.node.reach_genesis_block(b) assert self.node.broadcast.called