def fixture_data(): peerplays.clear() BettingMarkets.clear_cache() Rules.clear_cache() BettingMarketGroups.clear_cache() Proposals.clear_cache() Witnesses.clear_cache() Events.clear_cache() EventGroups.clear_cache() Sports.clear_cache() with open(os.path.join(os.path.dirname(__file__), "fixtures.yaml")) as fid: data = yaml.safe_load(fid) [Account(x) for x in data.get("accounts", [])] [Account(x).store(x, "name") for x in data.get("accounts", [])] Witnesses.cache_objects([Witness(x) for x in data.get("witnesses", [])]) Sports.cache_objects([Sport(x) for x in data.get("sports", [])]) EventGroups.cache_objects( [EventGroup(x) for x in data.get("eventgroups", [])]) Events.cache_objects([Event(x) for x in data.get("events", [])]) BettingMarketGroups.cache_objects( [BettingMarketGroup(x) for x in data.get("bettingmarketgroups", [])]) BettingMarkets.cache_objects( [BettingMarket(x) for x in data.get("bettingmarkets", [])]) Rules.cache_objects([Rule(x) for x in data.get("rules", [])]) [Bet(x) for x in data.get("bets", [])] proposals = [] for proposal in data.get("proposals", []): ops = list() for _op in proposal["operations"]: for opName, op in _op.items(): ops.append([operations[opName], op]) # Proposal! proposal_id = proposal["proposal_id"] proposal_data = { "available_active_approvals": [], "available_key_approvals": [], "available_owner_approvals": [], "expiration_time": "2018-05-29T10:23:13", "id": proposal_id, "proposed_transaction": { "expiration": "2018-05-29T10:23:13", "extensions": [], "operations": ops, "ref_block_num": 0, "ref_block_prefix": 0, }, "proposer": "1.2.7", "required_active_approvals": ["1.2.1"], "required_owner_approvals": [], } proposals.append(Proposal(proposal_data)) Proposals.cache_objects(proposals, "1.2.1") Proposals.cache_objects(proposals, "witness-account")
def test_approve_proposal(self): # We need an approver account self.lookup.set_approving_account("init0") # We need to delete id else, bos-sync will not try to create self.lookup["id"] = None self.lookup.clear_proposal_buffer() tx = self.lookup.propose_new() tx = tx.json() propops = tx["operations"][0][1]["proposed_ops"][0]["op"] Proposals._import( [ Proposal( { "available_active_approvals": [], "available_key_approvals": [], "available_owner_approvals": [], "expiration_time": "2018-05-17T15:20:25", "id": "1.10.2413", "proposed_transaction": { "expiration": "2018-05-17T15:17:48", "extensions": [], "operations": [propops], "ref_block_num": 0, "ref_block_prefix": 0, }, "proposer": "1.2.8", "required_active_approvals": ["1.2.1"], "required_owner_approvals": [], } ) ], "witness-account", ) # import logging # logging.basicConfig(level=logging.DEBUG) pending_propos = list(self.lookup.has_pending_new(require_witness=False)) self.assertTrue(len(pending_propos) > 0) self.assertIn(pending_propos[0]["pid"], self.lookup.approval_map) self.assertFalse(self.lookup.is_synced()) self.assertEqual(len(pending_propos), 1) self.assertEqual(pending_propos[0]["pid"], "1.10.2413") self.lookup.approve(**pending_propos[0]) self.assertNotIn(pending_propos[0]["pid"], self.lookup.approval_map)
def approve(self, pid, oid, **kwargs): """ Approve a proposal This call basically flags a single update operation of a proposal as "approved". Only if all operations in the proposal are approved, will this tool approve the whole proposal and otherwise ignore the proposal. The call has to identify the correct operation of a proposal on its own. Internally, a proposal is approved partially using a map that contains the approval of each operation in a proposal. Once all operations of a proposal are approved, the whole proopsal is approved. :param str pid: Proposal id :param int oid: Operation number within the proposal """ if pid[:3] == "0.0": log.info("Cannot approve pending-for-broadcast proposals") return assert self.approving_account, "No approving_account defined!" Lookup.approval_map[pid][oid] = True def pretty_proposal_map(): ret = dict() for k, v in Lookup.approval_map.items(): ret[k] = "{:.1f}".format(sum(v.values()) / len(v) * 100) return ret log.info("Approval Map: {}".format(pretty_proposal_map())) approved_read_for_delete = [] for p in Lookup.approval_map: if all(Lookup.approval_map[p].values()): proposal = Proposal(p) account = Account(self.approving_account) if account["id"] not in proposal["available_active_approvals"]: log.info("Approving proposal {} by {}".format( p, account["name"])) approved_read_for_delete.append(p) try: log.info(self.peerplays.approveproposal( p, account=self.approving_account, append_to=Lookup.direct_buffer )) except Exception as e: log.debug("Exception when approving proposal: {}".format( str(e))) # Not raising as at this point, the only reason for # this to fail is (probably) for the proposal to be # approved already - in the meantime. pass else: log.info( "Proposal {} has already been approved by {}".format( p, account["name"]) ) # In order not to approve the same proposal again and again, we remove # it from the map for p in approved_read_for_delete: del Lookup.approval_map[p]