def test_get_edges_by_type(self): res = get_edges_by_type(self.network, "support") self.assertEqual(len(res), 0) self.network.add_edge(0, 1, type="support") res = get_edges_by_type(self.network, "support") self.assertEqual(len(res), 1)
def test_setup_influence_edges_single_wont_overwrite_existing_influences( self): """ Test that setup_influence_edges_single will not overwrite existing influence edges. """ with patch('network_utils.influence') as mock: mock.return_value = 0.5 self.network = setup_influence_edges_single(self.network, 0) edges = list(get_edges_by_type(self.network, "influence")) self.assertEqual(len(edges), 8) # First, check that the influence edges all have the original # influence value of 0.5 for e in edges: self.assertEqual( self.network.get_edge_data(e[0], e[1])["influence"], 0.5) # Now, ensure that the original influence value of 0.5 was not # overwritten with 0.8 mock.return_value = 0.8 self.network = setup_influence_edges_single(self.network, 0) edges = list(get_edges_by_type(self.network, "influence")) self.assertEqual(len(edges), 8) for e in edges: self.assertEqual( self.network.get_edge_data(e[0], e[1])["influence"], 0.5)
def test_setup_influence_edges_single(self): """ Test that the code works, and that if I set up influence edges for a Participant in a network where he has 4 peers, 8 edges will be created, 4 from the new Participant to the existing Participants + 4 from the existing Participants to the new Participant """ with patch('network_utils.influence') as mock: mock.return_value = 0.5 self.network = setup_influence_edges_single(self.network, 0) edges = list(get_edges_by_type(self.network, "influence")) self.assertEqual(len(edges), 8) for e in edges: self.assertIsInstance(e[0], int) self.assertIsInstance(e[1], int) self.assertNotEqual(e[0], e[1]) # Test that Participant 0 has 4 edges to other Participants, and # that other Participants (like Participant 2) only have 1 edge to # Participant 0. a = tuple(zip(*edges)) self.assertEqual(a[0].count(0), 4) self.assertEqual(a[0].count(2), 1) self.assertEqual(a[1].count(0), 4) self.assertEqual(a[1].count(2), 1)
def setUp(self): self.params = { "debug": False, "days_to_80p_of_max_voting_weight": 10, "probability_func": new_probability_func(seed=None), "exponential_func": new_exponential_func(seed=None), "gamma_func": new_gamma_func(seed=None), "random_number_func": new_random_number_func(seed=None) } self.network = bootstrap_network([ TokenBatch(1000, 0, vesting_options=VestingOptions(10, 30)) for _ in range(4) ], 1, 3000, 4e6, 0.2, self.params["probability_func"], self.params["random_number_func"], self.params["gamma_func"], self.params["exponential_func"]) self.network, _ = add_proposal(self.network, Proposal(100, 1), self.params["random_number_func"]) """ For proper testing, we need to make sure the Proposals are CANDIDATE and ensure Proposal-Participant affinities are not some random value """ self.network.nodes[4]["item"].status = ProposalStatus.CANDIDATE self.network.nodes[5]["item"].status = ProposalStatus.CANDIDATE support_edges = get_edges_by_type(self.network, "support") for u, v in support_edges: self.network[u][v]["support"] = self.network[u][v][ "support"]._replace(affinity=0.9)
def su_calculate_conviction(params, step, sL, s, _input, **kwargs): """ Actually calculates the conviction. This function should only run ONCE per timestep/iteration! """ network = s["network"] alpha = params["alpha_days_to_80p_of_max_voting_weight"] support_edges = get_edges_by_type(network, "support") for i, j in support_edges: proposal_status = network.nodes[j]['item'].status if proposal_status == ProposalStatus.CANDIDATE: edge = network.edges[i, j] prior_conviction = edge['support'].conviction current_tokens = edge['support'].tokens edge['support'] = edge['support']._replace( conviction=current_tokens + alpha * prior_conviction) if params.get("debug") and s["timestep"] == 1: print( "ProposalFunding: Participant {} initially has staked {} tokens on Proposal {}, which will result in {} conviction in the next timestep" .format(i, current_tokens, j, edge["support"].conviction)) return "network", network
def test_setup_influence_edges_bulk_wont_overwrite_existing_influences(self): """ Test that setup_influence_edges_bulk will not overwrite existing influence edges. """ with patch('network_utils.influence') as mock: mock.return_value = 0.5 self.network = setup_influence_edges_bulk(self.network) edges = get_edges_by_type(self.network, "influence") self.assertEqual(len(edges), 20) for e in edges: self.assertEqual(self.network.get_edge_data( e[0], e[1])["influence"], 0.5) mock.return_value = 0.8 self.network = setup_influence_edges_bulk(self.network) edges = get_edges_by_type(self.network, "influence") self.assertEqual(len(edges), 20) for e in edges: self.assertEqual(self.network.get_edge_data( e[0], e[1])["influence"], 0.5)
def test_setup_conflict_edges_multiple(self): """ Test that the code works, and that edges are created between DIFFERENT nodes. Also ensures that edges refer to the node index, not the Proposal object stored within the node. """ self.network = setup_conflict_edges(self.network, rate=1) edges = get_edges_by_type(self.network, "conflict") self.assertEqual(len(edges), 20) for e in edges: self.assertIsInstance(e[0], int) self.assertIsInstance(e[1], int) self.assertNotEqual(e[0], e[1])
def test_setup_influence_edges_bulk(self): """ Test that the code works, and that edges are created between DIFFERENT nodes. Also ensures that edges refer to the node index, not the Participant object stored within the node. """ with patch('network_utils.influence') as mock: mock.return_value = 0.5 self.network = setup_influence_edges_bulk(self.network) edges = get_edges_by_type(self.network, "influence") self.assertEqual(len(edges), 20) for e in edges: self.assertIsInstance(e[0], int) self.assertIsInstance(e[1], int) self.assertNotEqual(e[0], e[1])
def setUp(self): self.network = bootstrap_network([ TokenBatch(1000, 0, vesting_options=VestingOptions(10, 30)) for _ in range(4) ], 1, 3000, 4e6, 0.2) self.network, _ = add_proposal(self.network, Proposal(100, 1)) self.params = {"debug": False, "days_to_80p_of_max_voting_weight": 10} """ For proper testing, we need to make sure the Proposals are CANDIDATE and ensure Proposal-Participant affinities are not some random value """ self.network.nodes[4]["item"].status = ProposalStatus.CANDIDATE self.network.nodes[5]["item"].status = ProposalStatus.CANDIDATE support_edges = get_edges_by_type(self.network, "support") for u, v in support_edges: self.network[u][v]["affinity"] = 0.9
def test_setup_conflict_edges_single(self): """ Test that the code works, and that edges are created between DIFFERENT nodes. Also ensures that edges refer to the node index, not the Proposal object stored within the node. """ proposal_count = len(get_proposals(self.network)) self.network = setup_conflict_edges(self.network, self.params["random_number_func"], 1, rate=1) edges = get_edges_by_type(self.network, "conflict") self.assertEqual(len(edges), proposal_count - 1) for e in edges: self.assertIsInstance(e[0], int) self.assertIsInstance(e[1], int) self.assertNotEqual(e[0], e[1])
def test_calc_total_conviction(self): """ Ensure that the function reports the correct sum of conviction from all support edges. """ self.network = setup_support_edges(self.network) ans = calc_total_conviction(self.network, 1) self.assertEqual(ans, 0) support_edges = get_edges_by_type(self.network, "support") # Every support edge gets a conviction value. Since there are 5 # Participants and 5 Proposals, this should result in a sum of 5 # conviction for each Proposal. for u, v in support_edges: self.network.edges[u, v]["conviction"] = 1 for i in [1, 3, 5, 7, 9]: ans = calc_total_conviction(self.network, i) self.assertEqual(ans, 5)
def test_su_calculate_conviction(self): """ Ensure that conviction was calculated correctly After the 1st iteration, 100 tokens staked becomes 100 conviction On the 2nd iteration, 100 current tokens + 10 days_to_80p_of_max_voting_weight * 100 prior conviction = 1100 conviction """ support_edges = get_edges_by_type(self.network, "support") for i, j in support_edges: self.network.edges[i, j]["support"] = self.network.edges[ i, j]["support"]._replace(tokens=100) n_0 = copy.copy(self.network) _, n_1 = ProposalFunding.su_calculate_conviction( self.params, 0, 0, { "network": n_0, "funding_pool": 1000, "token_supply": 1000 }, {}) # Make sure the conviction actually changed for i, j in support_edges: edge = n_1.edges[i, j] self.assertEqual(edge["support"].tokens, 100) self.assertEqual(edge["support"].conviction, 100) _, n_2 = ProposalFunding.su_calculate_conviction( self.params, 0, 0, { "network": copy.copy(n_1), "funding_pool": 1000, "token_supply": 1000 }, {}) for i, j in support_edges: edge = n_2.edges[i, j] self.assertEqual(edge["support"].tokens, 100) self.assertEqual(edge["support"].conviction, 1100)
def su_calculate_conviction(params, step, sL, s, _input, **kwargs): """ Actually calculates the conviction. This function should only run ONCE per timestep/iteration! """ network = s["network"] days_to_80p_of_max_voting_weight = params[0][ "days_to_80p_of_max_voting_weight"] support_edges = get_edges_by_type(network, "support") for i, j in support_edges: edge = network.edges[i, j] prior_conviction = edge['conviction'] current_tokens = edge['tokens'] edge['conviction'] = current_tokens + \ days_to_80p_of_max_voting_weight*prior_conviction if params[0].get("debug") and s["timestep"] == 1: print( "ProposalFunding: Participant {} initially has staked {} tokens on Proposal {}, which will result in {} conviction in the next timestep" .format(i, current_tokens, j, edge["conviction"])) return "network", network