def add(self, value): node = Node(value) if self.head is None: self.head = node self.tail = node else: node.previous = self.tail self.tail.next = node self.tail = node
def prepend(self, value): """ Adds the value to the start of the list :param value: the value to be added """ node = Node(value) node.next = self.head self.head = node
def tree_planter(df, class_var, var_desc, stop=50, variance=.2): if class_var not in df.columns: raise Exception('Class variable not in DataFrame') data = Data(df, class_var, var_desc) node = Node(data, stop=stop, variance=variance) node.split() return node
def insert_after_item(self, x, data): new_node = Node(data) while self.head.data != x and self.head: self.head = self.head.next if self.head is None: print("Item doesn't exist") return after_node = self.head.next self.head.next = new_node new_node.next = after_node
def prepend(self, value): """ Adds the value to the start of the list :param value: the value to be added """ new_node = Node(value) current_node = self.head new_node.next = current_node self.head = new_node
def tree_trainer(df, class_var, var_desc, stop=50, variance=.01): if class_var not in df.columns: raise Exception('Class variable not in DataFrame') data = Data(df, class_var, var_desc) node = Node(data, stop=stop, variance=variance) node.split() return node
def test_nodes_are_orderable(self): int1 = Node('3-#%3') int2 = Node('33-#%333') self.assertLess(int1, int2) word1 = Node('w$$ord') word2 = Node('3*45zebra') self.assertLess(word1, word2) self.assertRaises(ValueError, lambda: int1 < word2) self.assertRaises(ValueError, lambda: word2 < int1)
def add_node(self, count): for i in range(GENESIS_VALIDATORS_COUNT, GENESIS_VALIDATORS_COUNT+count): behaviour = Behaviour() behaviour.wants_to_hold_stake = True behaviour.epoch_to_release_stake = 2 logger = logging.getLogger("Node " + str(i)) keyless_node = Node(genesis_creation_time=self.genesis_creation_time, node_id=i, network=self.network, logger=logger) self.network.register_node(keyless_node) self.tasks.append(keyless_node.run())
def add(self, value): """ Adds the value to the end of the list :param value: the value to be added """ new_node = Node(value) if not self.head: self.head = new_node self.tail = self.head self.head.previous = None else: new_node.previous = self.tail self.tail.next = new_node self.tail = new_node
def launch(self): logger = logging.getLogger("Announce") announcer = AnnouncerNode(self.genesis_creation_time, logger) self.nodes.append(announcer) for i in range(0, GENESIS_VALIDATORS_COUNT): behaviour = self.generate_behaviour(i) # if i==7: # behaviour.malicious_wrong_signature = True # behavior for gossip emulation (create block but not broadcast) # if i == 3: # behaviour.transport_cancel_block_broadcast = True # uncomment the following line to enable logging only on specific node # if i != 13: logger.setLevel(logging.CRITICAL) logger = logging.getLogger("Node " + str(i)) node = Node(genesis_creation_time=self.genesis_creation_time, node_id=i, network=self.network, behaviour=behaviour, block_signer=self.private_keys.block_signers[i], logger=logger) if i == self.node_to_visualize_after_exit: self.node_to_visualize_after_exit = node self.network.register_node(node) self.nodes.append(node)
def __init__(self, original_string): # tokenize the input string node_list = [Node(x) for x in original_string.split()] # create an associated list marking int / word positions self._tag_list = [x.is_int() for x in node_list] # filter and sort word and int nodes self._word_list = sorted([x for x in node_list if x.is_word()]) self._int_list = sorted([x for x in node_list if x.is_int()])
def insert_at_end(self, data): new_node = Node(data) if self.head is None: self.head = new_node return while self.head.next: self.head = self.head.next self.head.next = new_node
def main(): args = parse_args() # Line just used for troubleshooting, should be removed before pulling into master # print args.verbose, args.node_type, args.port # Create node first = Node(args.node_type, args.port) print 'Node: {} created'.format(first) exit(0)
def generate_nodes(self, block_signers, count): behaviour = Behaviour() for i in range(0, count): logger = logging.getLogger("Node " + str(i)) node = Node(genesis_creation_time=1, node_id=i, network=self.network, behaviour=behaviour, block_signer=block_signers[i], logger=logger) self.network.register_node(node)
def test_is_int(self): self.assertTrue(Node('34').is_int()) self.assertTrue(Node('3-4').is_int()) self.assertTrue(Node('3%4').is_int()) self.assertTrue(Node('-3%4').is_int()) self.assertFalse(Node('-3a4').is_int()) self.assertFalse(Node('node').is_int())
def main(): # logging with an exclusion list log = LogHandler('20ft', 'node', [ 'Starting new HTTP connection', 'Injected into pty', 'Injected into process', 'stdin_process', 'stdin_container', 'tty_window', 'window size', 'Message.send', 'Message.receive', 'Message.reply' ]) # get user data ud = None try: with open("/opt/20ft/etc/noodle-bootstrap") as f: ud_txt = f.read() except FileNotFoundError: ud_txt = requests.get('http://169.254.169.254/latest/user-data').text try: ud = json.loads(ud_txt) except (json.decoder.JSONDecodeError, TypeError): print( "Could not bootstrap noodle, waiting for a bit then will restart..." ) time.sleep(10) exit(1) # go node = None try: node = Node(ud) node.run() finally: if node is not None: node.disconnect() log.stop()
def add_stakeholders(self, count): behaviour = Behaviour() behaviour.wants_to_hold_stake = True for i in range(0, count): index = len(self.network.nodes) logger = logging.getLogger("Node " + str(index)) node = Node(genesis_creation_time=1, block_signer=BlockSigner(Private.generate()), node_id=index, network=self.network, behaviour=behaviour, logger=logger) self.network.register_node(node)
def add(self, value): """ Adds the value to the end of the list :param value: the value to be added """ node = Node(value) if self.head is None: self.head = node self.tail = node else: self.tail.next = node self.tail = node
def add(self, value): """ Adds the value to the end of the list :param value: the value to be added """ new_node = Node(value) if not self.head: self.head = new_node self.tail = self.head else: current_node = self.tail current_node.next = new_node self.tail = current_node.next
def enqueue(self, val): node = Node(val) if self._length == 0: self.front = self.back = node self._length += 1 return node # self.back.next = self.back = node self.back.next = node self.back = node self._length += 1 return node
def add_to_tail(self, value): # wrap the input value in a node new_node = Node(value, None) # check if there is no head (i.e., the list is empty) if not self.head: # if the list is initially empty, set both head and tail to the # new node self.head = new_node self.tail = new_node # we have a non-empty list, add the new node to the tail else: # set the current tail's next reference to our new node self.tail.set_next(new_node) # set the list's tail reference to the new node self.tail = new_node
def main(): if len(argv) != 2: exit('Wrong args. Supply the snort logfile') alerts = [] snortNode = Node('snort', 13337) try: while True: try: pcap = rdpcap('/var/log/snort/{}'.format(argv[1])) except scapy.error.Scapy_Exception: continue try: last_pkt = pcap[-1] #last_pkt.display() except IndexError: continue if last_pkt not in alerts: alerts.append(last_pkt) sendSock = snortNode._bind('127.0.0.1', 13338) j = str_to_json(str(last_pkt[TCP].payload)) print send_message( sendSock, socketStr_to_tuple("127.0.0.1:50000"), vals_to_json(snortNode.id_str, 'exile', j['data']['orig_source'])) else: continue except KeyboardInterrupt: exit('Exiting Snory.py...')
def insert_at_index(self, index, data): if index == 1: new_node = Node(data) new_node.next = self.head self.head = new_node if index > 1: i = 1 while i < index - 1 and self.head: i = i + 1 self.head = self.head.next if self.head is None: print("Index out of bound") return new_node = Node(data) new_node.next = self.head.next self.head.next = new_node
def insert_before_item(self, x, data): if self.head is None: print("List has no element") return if self.head.data == x: new_node = Node(data) new_node.next = self.head self.head = new_node while self.head.next: if self.head.next.data == x: break self.head = self.head.next if self.head.next is None: print("Item doesn't exist") return new_node = Node(data) new_node.next = self.head.next self.head.next = new_node
def test_value_returns_appropriate_value(self): value_string = Node('333-#%4').value() self.assertEqual(3334, value_string) value_string = Node('w#3o5rd').value() self.assertEqual('word', value_string)
def test_value_string_returns_parsed_token(self): value_string = Node('333-#%4').value_string() self.assertEqual('3334', value_string) value_string = Node('w#3o5rd').value_string() self.assertEqual('word', value_string)
def test_is_word(self): self.assertFalse(Node('34').is_word()) self.assertTrue(Node('node').is_word()) self.assertTrue(Node('no-de').is_word()) self.assertTrue(Node('no$de').is_word())
""" Function that based on the count of the teams, returns the number of list spaces that is needed in order to generate a bracket that has enough room for them all. """ def count_of_leaves_to_tree_size(count): log = log2(count) if (log % 1 == 0): return int(2**(log + 1) - 1) log = floor(log) diff = count - 2**log extra_nodes = diff * 2 return int(2**(log + 1) - 1 + extra_nodes) teams = ["Sander", "Morten", "Jørgen", "Erlend", "Per", "Hans", "Jan", "Knut"] bracket = Bracket(tournament_name="CS:GO SAUDA TOURNAMENT") size_of_places = count_of_leaves_to_tree_size(len(teams)) nodes = [Node(match_nr=x) for x in range(size_of_places)] bracket.initiate_matches(nodes, teams) bracket.print_matches()
def test_maliciously_send_negative_and_positive_gossip(self): Time.use_test_time() Time.set_current_time(1) private_keys = BlockSigners() private_keys = private_keys.block_signers validators = Validators() validators.validators = Validators.read_genesis_validators_from_file() validators.signers_order = [0] + [1] + [2] + [3] + [ 4 ] + [5] * Epoch.get_duration() validators.randomizers_order = [0] * Epoch.get_duration() signer_index = 0 for i in Epoch.get_round_range(1, Round.PRIVATE): validators.signers_order[i] = signer_index signer_index += 1 network = Network() node0 = Node(genesis_creation_time=1, node_id=0, network=network, block_signer=private_keys[0], validators=validators, behaviour=Behaviour()) network.register_node(node0) behavior = Behaviour( ) # this node maliciously send positive and negative gossip behavior.malicious_send_negative_gossip_count = 1 behavior.malicious_send_positive_gossip_count = 1 node1 = Node(genesis_creation_time=1, node_id=1, network=network, block_signer=private_keys[1], validators=validators, behaviour=behavior) network.register_node(node1) node2 = Node(genesis_creation_time=1, node_id=2, network=network, block_signer=private_keys[2], validators=validators, behaviour=Behaviour()) network.register_node(node2) node3 = Node(genesis_creation_time=1, node_id=3, network=network, block_signer=private_keys[3], validators=validators, behaviour=Behaviour()) network.register_node(node3) node4 = Node(genesis_creation_time=1, node_id=4, network=network, block_signer=private_keys[4], validators=validators, behaviour=Behaviour()) network.register_node(node4) node5 = Node(genesis_creation_time=1, node_id=5, network=network, block_signer=private_keys[5], validators=validators, behaviour=Behaviour()) network.register_node(node5) helper = TestHelper(network) Time.advance_to_next_timeslot() # current block number 1 node0.step() # create and sign block # validate block created and broadcasted # validate mempool is empty # validate tx by hash is empty helper.list_validator(self, network.nodes, ['dag.blocks_by_number.length'], 2) helper.list_validator(self, network.nodes, ['mempool.gossips.length'], 0) # validate 2 public key tx helper.list_validator(self, network.nodes, ['dag.transactions_by_hash.length'], 1) # on one step sends +and- (add test for different steps ?) node1.step( ) # ! maliciously sand positive and negative gossip (request by genesis 0 block) # all node receive positive gossip # txs for now only in mempool (not in block) helper.list_validator(self, network.nodes, ['dag.blocks_by_number.length'], 2) # all nodes has 1-gossip and 6+gossips (1-gossip and 6+gossip from (0,1,2,3,4,5)) helper.list_validator(self, network.nodes, ['mempool.gossips.length'], 7) helper.list_validator(self, network.nodes, ['dag.transactions_by_hash.length'], 1) node2.step() node3.step() node4.step() node5.step() # after all steps situation same helper.list_validator(self, network.nodes, ['dag.blocks_by_number.length'], 2) helper.list_validator(self, network.nodes, ['mempool.gossips.length'], 7) helper.list_validator(self, network.nodes, ['dag.transactions_by_hash.length'], 1) Time.advance_to_next_timeslot() # current block number 2 node0.step() # do nothing node1.step( ) # is validator by order (need to marge mempool and provide block) # in current case node will penaltize SELF !!! helper.list_validator(self, network.nodes, ['dag.blocks_by_number.length'], 3) helper.list_validator(self, network.nodes, ['mempool.gossips.length'], 0) # tx_s # 3 - public key tx # 1 - negative gossip tx # 6 - positive gossip txs # 1 - penalty tx # total = 11 txs if ROUND_DURATION > 6: # total 6 nodes in test public_key_tx_count = 6 else: public_key_tx_count = ROUND_DURATION negative_gossip_tx_count = 1 positive_gossips_tx_count = 6 penalty_tx_count = 1 tx_total_count = public_key_tx_count + negative_gossip_tx_count + positive_gossips_tx_count + penalty_tx_count helper.list_validator(self, network.nodes, ['dag.transactions_by_hash.length'], tx_total_count) node2.step() node3.step() node4.step() node5.step() # validate that all keeps the same helper.list_validator(self, network.nodes, ['dag.blocks_by_number.length'], 3) helper.list_validator(self, network.nodes, ['mempool.gossips.length'], 0) helper.list_validator(self, network.nodes, ['dag.transactions_by_hash.length'], tx_total_count) # verify that node1 is steel in validators list helper.list_validator(self, network.nodes, ['permissions.epoch_validators.length'], GENESIS_VALIDATORS_COUNT) Time.advance_to_next_timeslot() # current block number 3 node0.step() # do nothing node1.step() # do nothing node2.step() # provide block node3.step() node4.step() node5.step() # validate new block by node2 helper.list_validator(self, network.nodes, ['dag.blocks_by_number.length'], 4) # verify that node1 is steel in validators list until epoch end helper.list_validator(self, network.nodes, ['permissions.epoch_validators.length'], GENESIS_VALIDATORS_COUNT) for i in range(5, ROUND_DURATION * 6 + 1): Time.advance_to_next_timeslot() if i == ROUND_DURATION * 6 + 1: node0.step() node0.step() node1.step() node2.step() node3.step() node4.step() node5.step() if i == ROUND_DURATION * 6 + 1: # ! chek up validators list on new epoch upcoming # TODO sometimes fall for unknoun reason # self.list_validator(network.nodes, ['dag.blocks_by_number.length'], i) for node in network.nodes: if len(node.dag.blocks_by_number) != i - 1: print('BLOCK_NUMBER : ' + str(i)) print('node id:' + str(node.node_id) + " dag.block_by_number:" + str(len(node1.dag.blocks_by_number))) helper.list_validator(self, network.nodes, ['permissions.epoch_validators.length'], GENESIS_VALIDATORS_COUNT - 1) # TODO nodes recalculates 2 times ? helper.list_validator( self, network.nodes, ['permissions.epoch_validators.epoch0.length'], GENESIS_VALIDATORS_COUNT - 1) # maybe 20 (on default block time and round duration) helper.list_validator( self, network.nodes, ['permissions.epoch_validators.epoch1.length'], GENESIS_VALIDATORS_COUNT - 1)
def test_maliciously_send_positive_gossip(self): Time.use_test_time() Time.set_current_time(1) private_keys = BlockSigners() private_keys = private_keys.block_signers validators = Validators() validators.validators = Validators.read_genesis_validators_from_file() validators.signers_order = [0, 1, 2, 3, 4, 5] * ROUND_DURATION * 6 validators.randomizers_order = [0] * Epoch.get_duration() network = Network() node0 = Node(genesis_creation_time=1, node_id=0, network=network, block_signer=private_keys[0], validators=validators, behaviour=Behaviour()) network.register_node(node0) behavior = Behaviour() # this node maliciously send positive gossip behavior.malicious_send_positive_gossip_count = 1 node1 = Node(genesis_creation_time=1, node_id=1, network=network, block_signer=private_keys[1], validators=validators, behaviour=behavior) network.register_node(node1) node2 = Node(genesis_creation_time=1, node_id=2, network=network, block_signer=private_keys[2], validators=validators, behaviour=Behaviour()) network.register_node(node2) node3 = Node(genesis_creation_time=1, node_id=3, network=network, block_signer=private_keys[3], validators=validators, behaviour=Behaviour()) network.register_node(node3) node4 = Node(genesis_creation_time=1, node_id=4, network=network, block_signer=private_keys[4], validators=validators, behaviour=Behaviour()) network.register_node(node4) node5 = Node(genesis_creation_time=1, node_id=5, network=network, block_signer=private_keys[5], validators=validators, behaviour=Behaviour()) network.register_node(node5) helper = TestHelper(network) Time.advance_to_next_timeslot() # current block number 1 node0.step() # create and sign block # validate block created and broadcasted # validate mempool is empty helper.list_validator(self, network.nodes, ['dag.blocks_by_number.length'], 2) helper.list_validator(self, network.nodes, ['mempool.gossips.length'], 0) node1.step( ) # ! maliciously sand positive gossip (request by genesis 0 block) # all node receive positive gossip # txs for now only in mempool (not in block) helper.list_validator(self, network.nodes, ['dag.blocks_by_number.length'], 2) # all nodes has 1+gossips helper.list_validator(self, network.nodes, ['mempool.gossips.length'], 1) node2.step() node3.step() node4.step() node5.step() # after all steps situation same helper.list_validator(self, network.nodes, ['dag.blocks_by_number.length'], 2) helper.list_validator(self, network.nodes, ['mempool.gossips.length'], 1) Time.advance_to_next_timeslot() # current block number 2 node0.step() # do nothing node1.step( ) # is validator by order (need to marge mempool and provide block) # возможно добавить проверку на малишес скип блок в добавок ? # (по идеи все должны еще раз обменятся госипами и уже не найти блок 2) # (в таком случае следующий валидатор должен смерджить все и отправить блок) # (нода 1 должна быть исключена из списка валидаторов ?) # after node create and sign block all node clean its mem pool # here we have 3 blocks, empty mem pools, and transaction in dag.transaction_by_hash helper.list_validator(self, network.nodes, ['dag.blocks_by_number.length'], 3) helper.list_validator(self, network.nodes, ['mempool.gossips.length'], 0) node2.step() node3.step() node4.step() node5.step() # validate that all keeps the same helper.list_validator(self, network.nodes, ['dag.blocks_by_number.length'], 3) helper.list_validator(self, network.nodes, ['mempool.gossips.length'], 0) Time.advance_to_next_timeslot() # current block number 3 node0.step() # do nothing node1.step() # do nothing node2.step() # provide block node3.step() node4.step() node5.step() # validate new block by node2 helper.list_validator(self, network.nodes, ['dag.blocks_by_number.length'], 4)
self.magnitude = mag( node_a - node_b ) # Marker so that this bond doesn't have to be looked for again # while searching. # MAKE SURE TO RESET TO FALSE IF CHANGED self.not_found = False # Should not connect at this point, connecting requires having # a list of all the atoms, hence connecting should be handled by # the Chain class # self.node_a.connect( node_b ) if __name__ == '__main__': import sys sys.path.append( "../" ) from node.node import Node import math my_node = Node( 'AB12', -1.0, 2.0, 3.0 ) print my_node, ' ', id(my_node) my_node.rotate_with( pi/2, (0, 0, 1) ) print my_node, ' ', id(my_node) negative_node = my_node negative_node *= -1 # Plus equals does not create new object, check my_node += negative_node print my_node, ' ', id( my_node ), ' ', type( my_node ) # Use 1 rotation to rotate into x axis diff_angle = negative_node.diff_angle( (1, 0, 0) ) normal = negative_node.cross( (1, 0, 0) ) negative_node.rotate_with( diff_angle, normal ) print diff_angle, '\n', normal, '\n', negative_node
# but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with Project Master Device. If not, see <http://www.gnu.org/licenses/>. import os from shared import log, config, database from node.node import Node default_log_conf_path = os.path.dirname(os.path.abspath(__file__)) + '/../config/node_logging.conf' default_conf_path = os.path.dirname(os.path.abspath(__file__)) + '/../config/node_config.yml' log.initialize(default_log_conf_path) config.initialize(default_conf_path) db_connection_string = 'sqlite:' + os.path.abspath(config.config()['database']['filename']) db_debug_mode = config.config()['database']['debug'] database.initialize(db_connection_string, db_debug_mode) if __name__ == '__main__': try: node = Node() node.start() except KeyboardInterrupt: log.logger().warning('Stopping node on user command.') node.stop()
def test_negative_gossip_by_zeta(self): Time.use_test_time() Time.set_current_time(1) private_keys = BlockSigners() private_keys = private_keys.block_signers validators = Validators() validators.validators = Validators.read_genesis_validators_from_file() validators.signers_order = [0] + [1] + [2] + [3] + [ 4 ] + [5] * Epoch.get_duration() validators.randomizers_order = [0] * Epoch.get_duration() network = Network() node0 = Node(genesis_creation_time=1, node_id=0, network=network, block_signer=private_keys[0], validators=validators, behaviour=Behaviour()) network.register_node(node0) behavior = Behaviour() # this node malicious skip block behavior.malicious_skip_block = True node1 = Node(genesis_creation_time=1, node_id=1, network=network, block_signer=private_keys[1], validators=validators, behaviour=behavior) network.register_node(node1) node2 = Node(genesis_creation_time=1, node_id=2, network=network, block_signer=private_keys[2], validators=validators, behaviour=Behaviour()) network.register_node(node2) node3 = Node(genesis_creation_time=1, node_id=3, network=network, block_signer=private_keys[3], validators=validators, behaviour=Behaviour()) network.register_node(node3) node4 = Node(genesis_creation_time=1, node_id=4, network=network, block_signer=private_keys[4], validators=validators, behaviour=Behaviour()) network.register_node(node4) node5 = Node(genesis_creation_time=1, node_id=5, network=network, block_signer=private_keys[5], validators=validators, behaviour=Behaviour()) network.register_node(node5) helper = TestHelper(network) Time.advance_to_next_timeslot() # current block number 1 node0.step() # create and sign block node1.step() node2.step() node3.step() node4.step() node5.step() # validate block created and broadcasted helper.list_validator(self, network.nodes, ['dag.blocks_by_number.length'], 2) Time.advance_to_next_timeslot() # current block number 1 node0.step() node1.step() # skip block creation node2.step() node3.step() node4.step() node5.step() # validate block NOT created and NOT broadcasted helper.list_validator(self, network.nodes, ['dag.blocks_by_number.length'], 2) Time.advance_to_next_timeslot() # current block number 2 # for now all chain do not have block from previous timeslot node0.step() # broadcast negative gossip # all nodes handle negative gossips by node0 # not broadcast to self (ADD TO MEMPOOL before broadcast) helper.list_validator(self, network.nodes, ['mempool.gossips.length'], 0) # not permited for gossip send node1.step() # broadcast negative gossip helper.list_validator(self, network.nodes, ['mempool.gossips.length'], 1) node2.step( ) # broadcast negative gossip AND skip block signing for current step !!! node3.step() # broadcast negative gossip node4.step() # broadcast negative gossip node5.step( ) # VALIDATE 5 NEGATIVE GOSSIPS AND DO NOT BROADCAST ANOTHER ONE (current ZETA == 5) # GOSSIPS may be more - see test_negative_gossips_zata_validators helper.list_validator(self, network.nodes, ['mempool.gossips.length'], 5) # duplicate gossips tx will NOT include to mempool ! # if node already send negative gossip IT NOT broadcast it again ! # if node already have x < ZETA (x - different negative gossips by block count) IT NOT broadcast it again ! Time.advance_time(1) # advance time by one second in current timeslot # make steps by nodes node0.step() # node1.step() # # steel 5 negative gossips (from 0,1,2,3,4) on all nodes (add validation ?) helper.list_validator(self, network.nodes, ['mempool.gossips.length'], 5) node2.step( ) # CREATE, SIGN, BROADCAST block (block by node1 not exist) # all nodes handle new block helper.list_validator(self, network.nodes, ['dag.blocks_by_number.length'], 3) # gossips cleaned from mem pool by block handling helper.list_validator(self, network.nodes, ['mempool.gossips.length'], 0) node3.step() # node4.step() # node5.step() # # provide validation for next normal block and FOR GOSSIPS is NOT in mempool after next block Time.advance_to_next_timeslot() # current block number 3 node0.step() # node1.step() # node2.step() # node3.step( ) # must create and sign and broadcast block (all gossips MUST be mined and erased from mempool) node4.step() # node5.step() # # after node2 step helper.list_validator(self, network.nodes, ['dag.blocks_by_number.length'], 4) helper.list_validator(self, network.nodes, ['mempool.gossips.length'], 0)