コード例 #1
0
class CRCProposalReview(Payload):
    APPROVE = 0x00
    REJECT = 0x01
    ABSTAIN = 0x02

    def __init__(self, private_key: str, proposal_hash: bytes, vote_result: int, opinion_hash: bytes):
        Payload.__init__(self, self.DEFAULT_VERSION)
        self.account = Account(private_key)
        self.proposal_hash = proposal_hash
        self.vote_result = vote_result
        self.opinion_hash = opinion_hash
        self.did = bytes.fromhex(self.account.did())
        self.sign = None
        self.gen_signature()
        self.serialize_data = None

    def data(self, version: int):
        if self.serialize_data is not None:
            return self.serialize_data
        r = b""
        r = self.serialize(r, self.version)
        self.serialize_data = r
        return r

    def serialize(self, r: bytes, version: int):
        r = self.serialize_unsigned(r, version)
        r = serialize.write_var_bytes(r, self.sign)
        return r

    def serialize_unsigned(self, r: bytes, version=0):
        r += self.proposal_hash
        r += struct.pack("<B", self.vote_result)
        r += self.opinion_hash
        r += self.did
        return r

    def deserialize(self, r: bytes, version: int):
        pass

    def gen_signature(self):
        r = b""
        r = self.serialize_unsigned(r, self.version)
        self.sign = keytool.ecdsa_sign(bytes.fromhex(self.account.private_key()), r)
        return r

    def __repr__(self):
        return "CRCProposalReview {" + "\n\t" \
               + "privateKey: {}".format(self.account.private_key()) + "\n\t" \
               + "proposalHash: {}".format(self.proposal_hash.hex()) + "\n\t" \
               + "voteResult : {}".format(self.vote_result) + "\n\t" \
               + "crOpinionHash: {}".format(self.opinion_hash.hex()) + "\n\t" \
               + "did : {}".format(keytool.create_address(self.did)) + "\n\t" \
               + "sign: {}".format(self.sign.hex()) + "\n\t" \
               + "}"
コード例 #2
0
    def _create_account_data(self, account: Account, account_type: str):
        private_key_encrypted = keytool.encrypt_private_key(
            self._master_key, bytes.fromhex(account.private_key()),
            account.ecc_public_key(), self._iv)

        account_data = dict()
        account_data["Address"] = account.address()
        account_data["ProgramHash"] = account.program_hash()
        account_data["RedeemScript"] = account.redeem_script()
        account_data["PrivateKeyEncrypted"] = private_key_encrypted.hex()
        account_data["Type"] = account_type

        return account_data
コード例 #3
0
class CRCProposalWithdraw(Payload):
    def __init__(self, private_key: str, proposal_hash: bytes):
        Payload.__init__(self, self.DEFAULT_VERSION)
        self.account = Account(private_key)
        self.proposal_hash = proposal_hash
        self.sponsor_public_key = bytes.fromhex(self.account.public_key())
        self.sign = None
        self.gen_signature()
        self.serialize_data = None

    def data(self, version: int):
        if self.serialize_data is not None:
            return self.serialize_data
        r = b""
        r = self.serialize(r, self.version)
        self.serialize_data = r
        return r

    def serialize(self, r: bytes, version: int):
        r = self.serialize_unsigned(r, version)
        r = serialize.write_var_bytes(r, self.sign)
        return r

    def serialize_unsigned(self, r: bytes, version=0):
        r += self.proposal_hash
        r = serialize.write_var_bytes(r, self.sponsor_public_key)
        return r

    def deserialize(self, r: bytes, version: int):
        pass

    def gen_signature(self):
        r = b""
        r = self.serialize_unsigned(r, self.version)
        self.sign = keytool.ecdsa_sign(
            bytes.fromhex(self.account.private_key()), r)
        return r

    def __repr__(self):
        return "CRCProposalWithdraw {" + "\n\t" \
               + "proposalHash: {}".format(self.proposal_hash.hex()) + "\n\t" \
               + "sponsorPublicKey : {}".format(self.sponsor_public_key.hex()) + "\n\t" \
               + "sign: {}".format(self.sign.hex()) + "\n\t" \
               + "}"
コード例 #4
0
class UnRegisterCR(Payload):
    def __init__(self, register_private_key: str):
        Payload.__init__(self, self.DEFAULT_VERSION)
        self.account = Account(register_private_key)
        self.cid = self.account.cid()
        self.signature = None
        self.gen_signature()
        self.serialize_data = None

    def gen_signature(self):
        r = b""
        r = self.serialize_unsigned(r, self.version)
        signature = keytool.ecdsa_sign(
            bytes.fromhex(self.account.private_key()), r)
        self.signature = signature

    def data(self, version: int):
        r = b""
        if self.serialize_data is not None:
            return self.serialize_data

        r = self.serialize(r, self.version)
        self.serialize_data = r
        return r

    def serialize(self, r: bytes, version: int):
        r = self.serialize_unsigned(r, self.version)
        if self.signature is not None:
            r = serialize.write_var_bytes(r, self.signature)
        return r

    def serialize_unsigned(self, r: bytes, version: int):
        r += bytes.fromhex(self.cid)

        return r

    def deserialize(self, r: bytes, version: int):
        pass
コード例 #5
0
class CRCProposalTracking(Payload):
    COMMON = 0x00
    PROGRESS = 0x01
    REJECTED = 0x02
    TERMINATED = 0x03
    PROPOSAL_LEADER = 0x04
    FINALIZED = 0x05

    DEFAULT = 0x00

    def __init__(self, secretary_private_key: str, leader_private_key: str,
                 new_leader_private_key, tracking_type: int,
                 proposal_hash: bytes, document_hash: bytes, stage: int,
                 secretary_opinion_hash: bytes):
        Payload.__init__(self, self.DEFAULT_VERSION)
        self.secretary_general_account = Account(secretary_private_key)
        self.leader_account = Account(leader_private_key)
        self.new_leader_account = None
        self.proposal_hash = proposal_hash
        self.document_hash = document_hash
        self.stage = stage
        self.leader_public_key = bytes.fromhex(
            self.leader_account.public_key())
        self.new_leader_public_key = None
        self.proposal_tracking_type = tracking_type
        self.secretary_opinion_hash = secretary_opinion_hash
        self.secretary_general_sign = None
        self.leader_sign = None
        self.new_leader_sign = None
        self._get_new_leader_account(new_leader_private_key)
        self.gen_signature()
        self.serialize_data = None

    def data(self, version: int):
        if self.serialize_data is not None:
            return self.serialize_data
        r = b""
        r = self.serialize(r, self.version)
        self.serialize_data = r
        return r

    def serialize(self, r: bytes, version: int):
        r = self.serialize_unsigned(r, version)
        r = serialize.write_var_bytes(r, self.leader_sign)
        if self.new_leader_sign is not None:
            r = serialize.write_var_bytes(r, self.new_leader_sign)
        else:
            r += struct.pack("<B", CRCProposalTracking.DEFAULT)
        r += struct.pack("<B", self.proposal_tracking_type)
        r += self.secretary_opinion_hash
        r = serialize.write_var_bytes(r, self.secretary_general_sign)
        return r

    def serialize_unsigned(self, r: bytes, version=0):
        r += self.proposal_hash
        r += self.document_hash
        r += serialize.write_var_uint(self.stage)
        r = serialize.write_var_bytes(r, self.leader_public_key)
        if self.new_leader_public_key is not None:
            r = serialize.write_var_bytes(r, self.new_leader_public_key)
        else:
            r += struct.pack("<B", CRCProposalTracking.DEFAULT)
        return r

    def deserialize(self, r: bytes, version: int):
        pass

    def gen_signature(self):
        r = b""
        r = self.serialize_unsigned(r, self.version)
        self.leader_sign = keytool.ecdsa_sign(
            bytes.fromhex(self.leader_account.private_key()), r)
        r = serialize.write_var_bytes(r, self.leader_sign)
        if self.new_leader_account is not None:
            self.new_leader_sign = keytool.ecdsa_sign(
                bytes.fromhex(self.new_leader_account.private_key()), r)
            r = serialize.write_var_bytes(r, self.new_leader_sign)
        else:
            self.new_leader_sign = None
            r += struct.pack("<B", CRCProposalTracking.DEFAULT)
        r += struct.pack("<B", self.proposal_tracking_type)
        r += self.secretary_opinion_hash
        self.secretary_general_sign = keytool.ecdsa_sign(
            bytes.fromhex(self.secretary_general_account.private_key()), r)
        return r

    def _get_new_leader_account(self, new_leader_private_key):
        if new_leader_private_key is not None:
            self.new_leader_account = Account(new_leader_private_key)
            self.new_leader_public_key = bytes.fromhex(
                self.new_leader_account.public_key())

    def __repr__(self):
        return "CRCProposalTracking {" + "\n\t" \
               + "SecretaryGeneralPrivateKey: {}".format(self.secretary_general_account.private_key()) + "\n\t" \
               + "proposalTrackingType: {}".format(self.proposal_tracking_type) + "\n\t" \
               + "proposalHash: {}".format(self.proposal_hash.hex()) + "\n\t" \
               + "documentHash : {}".format(self.document_hash) + "\n\t" \
               + "stage : {}".format(self.stage) + "\n\t" \
               + "leaderPublicKey: {}".format(self.leader_public_key.hex()) + "\n\t" \
               + "newLeaderPublicKey: {}".format(self.new_leader_public_key) + "\n\t" \
               + "leaderSign: {}".format(self.leader_sign.hex()) + "\n\t" \
               + "newLeaderSign: {}".format(self.new_leader_sign) + "\n\t" \
               + "secretaryOpinionHash: {}".format(self.secretary_opinion_hash) + "\n\t" \
               + "secretaryGeneralSign: {}".format(self.secretary_general_sign.hex()) + "\n\t" \
               + "}"
コード例 #6
0
    def _create_keystore(self, category: str, num: int):
        keystore_saved_dir = os.path.join(self.key_message_saved_dir, category)
        if not os.path.exists(keystore_saved_dir):
            os.makedirs(keystore_saved_dir)

        for i in range(num):
            if i == 0:
                first_time = True
            else:
                first_time = False

            if category == "arbiter":
                a = Account(self.node_accounts[i].private_key())
            else:
                a = Account()
            Logger.debug("{} {}_{} private key: {}".format(
                self.tag, category, i, a.private_key()))
            k = Keystore(a, self.password)
            self.category_dict[category].append(a)

            if category == "arbiter":
                sub1 = Account()
                k.add_sub_account(sub1)
                self.sub1_accounts.append(sub1)
                util.save_to_json(
                    sub1, "sub1_" + str(i),
                    os.path.join(self.key_message_saved_dir, "sub1.json"),
                    first_time)

                sub2 = Account()
                k.add_sub_account(sub2)
                self.sub2_accounts.append(sub2)
                util.save_to_json(
                    sub2, "sub2_" + str(i),
                    os.path.join(self.key_message_saved_dir, "sub2.json"),
                    first_time)

                sub3 = Account()
                k.add_sub_account(sub3)
                self.sub3_accounts.append(sub3)
                util.save_to_json(
                    sub3, "sub3_" + str(i),
                    os.path.join(self.key_message_saved_dir, "sub3.json"),
                    first_time)

                sub4 = Account()
                k.add_sub_account(sub4)
                self.sub3_accounts.append(sub4)
                util.save_to_json(
                    sub4, "sub4_" + str(i),
                    os.path.join(self.key_message_saved_dir, "sub4.json"),
                    first_time)

            util.save_to_json(
                a, category + "_" + str(i),
                os.path.join(self.key_message_saved_dir, category + ".json"),
                first_time)
            util.save_to_dat(
                k.key_store_dict(),
                os.path.join(keystore_saved_dir, category + str(i) + ".dat"))

        Logger.debug("{} create {} keystores on success!".format(
            self.tag, category))
コード例 #7
0
class Controller(object):
    PRODUCER_STATE_ACTIVE = "Active"
    PRODUCER_STATE_INACTIVE = "Inactive"

    # CR_Foundation_TEMP = "EULhetag9FKS6Jd6aifFaPqjFTpZbSMY7u"
    CR_Foundation_TEMP = "CRASSETSXXXXXXXXXXXXXXXXXXXX2qDX5J"
    SECRETARY_PRIVATE_KEY = "E0076A271A137A2BD4429FA46E79BE3E10F2A730585F8AC2763D570B60469F11"
    CRC_COMMITTEE_ADDRESS = "CREXPENSESXXXXXXXXXXXXXXXXXX4UdT6b"

    def __init__(self, up_config: dict):
        self.tag = util.tag_from_path(__file__, Controller.__name__)

        # set config
        self.up_config = up_config
        self.root_path = os.path.abspath(
            os.path.join(os.path.abspath(__file__), "../../../"))
        self.config = util.read_config_file(
            os.path.join(self.root_path, "config.json"))
        self.node_types = ["ela", "arbiter", "did", "token", "neo"]
        self.reset_config(up_config)

        self.params = Parameter(self.config, self.root_path)
        self.check_params()
        self.env_manager = EnvManager()
        self.keystore_manager = KeyStoreManager(self.params)

        self.node_manager = NodeManager(self.params, self.env_manager,
                                        self.keystore_manager)
        self.tx_manager = TransactionManager(self.node_manager)
        # init tap amount and register amount(unit: ELA)
        self.tap_amount = 20000000
        self.register_amount = 6000
        self.node_amount = 5000
        # necessary keystore
        self.foundation_account = self.keystore_manager.foundation_account
        self.tap_account = self.keystore_manager.tap_account
        # pressure keystore
        self.pressure_account = Account()
        self.init_for_testing()
        self.later_nodes = self.node_manager.ela_nodes[(
            self.params.ela_params.number -
            self.params.ela_params.later_start_number + 1):]

        self.dpos_votes_dict = dict()
        self.crc_proposal_hash = bytes()
        self.owner_private_key = None
        self.secretary_private_key = self.SECRETARY_PRIVATE_KEY

    def init_for_testing(self):
        self.node_manager.deploy_nodes()
        Logger.info("{} deploying nodes on success!".format(self.tag))
        self.node_manager.start_nodes()
        self.node_manager.create_address_name_dict()
        self.node_manager.create_owner_pubkey_name_dict()
        self.node_manager.create_node_pubkey_name_dict()
        self.node_manager.create_normal_dpos_pubkey()
        Logger.info("{} starting nodes on success!".format(self.tag))
        self.mining_blocks_ready(self.foundation_account.address())
        Logger.info("{} mining 110 blocks on success!".format(self.tag))
        time.sleep(5)

        ret = self.tx_manager.recharge_necessary_keystore(
            input_private_key=self.foundation_account.private_key(),
            accounts=[self.tap_account],
            amount=self.tap_amount * constant.TO_SELA)

        self.check_result("recharge tap keystore", ret)

        Logger.info("{} recharge tap keystore {} ELAs on success!".format(
            self.tag, self.tap_amount * constant.TO_SELA))

        ret = self.tx_manager.recharge_necessary_keystore(
            input_private_key=self.tap_account.private_key(),
            accounts=self.keystore_manager.owner_accounts,
            amount=self.register_amount * constant.TO_SELA)

        self.check_result("recharge owner keystore", ret)

        ret = self.tx_manager.recharge_necessary_keystore(
            input_private_key=self.tap_account.private_key(),
            accounts=self.keystore_manager.node_accounts,
            amount=self.node_amount * constant.TO_SELA)

        self.check_result("recharge node keystore", ret)

        Logger.info("{} recharge producer on success!".format(self.tag))

        if self.params.arbiter_params.enable:
            ret = self.tx_manager.recharge_necessary_keystore(
                input_private_key=self.tap_account.private_key(),
                accounts=self.keystore_manager.sub1_accounts,
                amount=3 * constant.TO_SELA)
            self.check_result("recharge sub1 keystore", ret)
            Logger.info("{} recharge each sub1 keystore {} ELAs on success!")

            ret = self.tx_manager.recharge_necessary_keystore(
                input_private_key=self.tap_account.private_key(),
                accounts=self.keystore_manager.sub2_accounts,
                amount=3 * constant.TO_SELA)
            self.check_result("recharge sub2 keystore", ret)
            Logger.info("{} recharge each sub2 keystore {} ELAs on success!")

            ret = self.tx_manager.recharge_necessary_keystore(
                input_private_key=self.tap_account.private_key(),
                accounts=self.keystore_manager.sub3_accounts,
                amount=3 * constant.TO_SELA)
            self.check_result("recharge sub3 keystore", ret)
            Logger.info("{} recharge each sub3 keystore {} ELAs on success!")

            ret = self.tx_manager.recharge_necessary_keystore(
                input_private_key=self.tap_account.private_key(),
                accounts=self.keystore_manager.sub4_accounts,
                amount=3 * constant.TO_SELA)
            self.check_result("recharge sub4 keystore", ret)
            Logger.info("{} recharge each sub4 keystore {} ELAs on success!")

    def ready_for_pressure_inputs(self, inputs_num: int):
        ret = self.pressure_inputs(inputs_num)
        self.check_result("pressure inputs number:{}".format(inputs_num), ret)
        Logger.info("{}pressure inputs on success!".format(self.tag))

    def ready_for_pressure_big_block(self, data_size: int):
        ret = self.pressure_big_block(data_size)
        self.check_result("pressure big block size:{} ".format(data_size), ret)
        Logger.info("{}pressure big block on success!".format(
            self.tag, data_size))

    def pressure_inputs(self, inputs_num: int):
        output_addresses = list()
        for i in range(inputs_num):
            output_addresses.append(self.pressure_account.address())
        ret = self.tx_manager.transfer_asset(self.tap_account.private_key(),
                                             output_addresses,
                                             1 * util.TO_SELA)
        if ret:
            self.wait_block()
            value = rpc.get_balance_by_address(self.pressure_account.address())
            Logger.debug("{} account {} wallet balance: {}".format(
                self.tag, self.pressure_account.address(), value))

            ret = self.tx_manager.transfer_asset(
                self.pressure_account.private_key(),
                [self.pressure_account.address()],
                int(Decimal(value) * util.TO_SELA - util.TX_FEE))
            if ret:
                self.wait_block()
                return True
            else:
                Logger.error("{} pressure inputs transfer failed".format(
                    self.tag))
                return False
        else:
            Logger.error("{} pressure outupts transfer failed".format(
                self.tag))

        return ret

    def pressure_big_block(self, data_size):
        attributes = list()
        attribute = Attribute(usage=Attribute.NONCE,
                              data=Random.get_random_bytes(data_size))
        attributes.append(attribute)
        ret = self.tx_manager.transfer_abnormal_asset(
            self.tap_account.private_key(), [self.tap_account.address()],
            1 * util.TO_SELA,
            attributes=attributes)
        if ret:
            self.wait_block()
            return True
        else:
            Logger.error("{} pressure big block transfer failed".format(
                self.tag))
            return False

    def wait_block(self):
        Logger.info("waiting for the block ... ")
        count_height = 0
        height = self.get_current_height()
        while True:
            if height + 1 >= count_height:
                rpc.discrete_mining(1)
                time.sleep(1)
                count_height = self.get_current_height()
            else:
                break

    def ready_for_dpos(self):
        ret = self.tx_manager.register_producers_candidates()
        self.check_result("register producers", ret)
        Logger.info("{} register producers on success!".format(self.tag))
        ret = self.tx_manager.vote_producers_candidates()
        self.check_result("vote producers", ret)
        Logger.info("{} vote producer on success!".format(self.tag))
        self.get_dpos_votes()

    def ready_for_cr(self):
        ret = self.register_cr_candidates()
        self.get_current_height()
        self.check_result("register cr", ret)
        Logger.info("{} register cr on success!".format(self.tag))

        ret = self.tx_manager.vote_cr_candidates()
        self.get_current_height()
        self.check_result("vote cr", ret)
        Logger.info("{} vote cr on success!".format(self.tag))

        # transfer to CRFoundation
        # self.tx_manager.transfer_asset(self.tap_account.private_key(), [self.CR_Foundation_TEMP], 5000 * util.TO_SELA)
        # if ret:
        #     rpc.discrete_mining(1)
        #     value = rpc.get_balance_by_address(self.CR_Foundation_TEMP)
        #     Logger.debug("{} CRFoundation {} wallet balance: {}".format(self.tag, self.CR_Foundation_TEMP, value))
        # else:
        #     Logger.error("{} CRFoundation transfer failed".format(self.tag))
        self.tx_manager.transfer_asset(self.tap_account.private_key(),
                                       [self.CRC_COMMITTEE_ADDRESS],
                                       5000 * util.TO_SELA)
        if ret:
            rpc.discrete_mining(1)
            value = rpc.get_balance_by_address(self.CRC_COMMITTEE_ADDRESS)
            Logger.debug("{} CRFoundation {} wallet balance: {}".format(
                self.tag, self.CRC_COMMITTEE_ADDRESS, value))
        else:
            Logger.error("{} CRFoundation transfer failed".format(self.tag))

    def ready_for_crc_proposal(self):
        ret = self.crc_proposal()
        self.get_current_height()
        self.check_result("crc proposal", ret)
        Logger.info("{} crc proposal on success!".format(self.tag))

    def ready_for_crc_proposal_secretary_general(self):
        ret = self.crc_proposal_secretary_general()
        self.get_current_height()
        self.check_result("crc proposal change secretary general", ret)
        Logger.info(
            "{} crc proposal change secretary general on success!".format(
                self.tag))

    def ready_for_crc_proposal_change_owner(self):
        ret = self.crc_proposal_change_owner()
        self.get_current_height()
        self.check_result("crc proposal change owner", ret)
        Logger.info("{} crc proposal change owneron success!".format(self.tag))

    def ready_for_crc_proposal_review(self):
        ret = self.crc_proposal_review()
        self.get_current_height()
        self.check_result("crc proposal review", ret)
        Logger.info("{} crc proposal review on success!".format(self.tag))
        self.discrete_miner(self.params.ela_params.proposal_cr_voting_period)

        ret = self.tx_manager.vote_crc_proposal_candidates(
            self.crc_proposal_hash)
        self.get_current_height()
        self.check_result("vote cr proposal", ret)
        Logger.info("{} vote crc proposal  on success!".format(self.tag))
        self.discrete_miner(
            self.params.ela_params.proposal_public_voting_period)

    def ready_for_crc_proposal_tracking(self):
        # common
        ret = self.crc_proposal_tracking(None, CRCProposalTracking.COMMON, 0)
        self.get_current_height()
        self.check_result("crc proposal tracking common type", ret)
        Logger.info("{} crc proposal tracking common on success!".format(
            self.tag))

        # progress
        ret = self.crc_proposal_tracking(None, CRCProposalTracking.PROGRESS, 1)
        self.get_current_height()
        self.check_result("crc proposal tracking progress type", ret)
        Logger.info("{} crc proposal tracking progress on success!".format(
            self.tag))

        # Reject
        ret = self.crc_proposal_tracking(None, CRCProposalTracking.REJECTED, 2)
        self.get_current_height()
        self.check_result("crc proposal tracking reject type", ret)
        Logger.info("{} crc proposal tracking reject on success!".format(
            self.tag))

        # progress
        ret = self.crc_proposal_tracking(None, CRCProposalTracking.PROGRESS, 2)
        self.get_current_height()
        self.check_result("crc proposal tracking progress type", ret)
        Logger.info("{} crc proposal tracking progress on success!".format(
            self.tag))

        # proposal leader
        ela_node = self.node_manager.ela_nodes[2]
        new_leader_private_key = ela_node.cr_account.private_key()
        ret = self.crc_proposal_tracking(new_leader_private_key,
                                         CRCProposalTracking.PROPOSAL_LEADER,
                                         0)
        self.get_current_height()
        self.check_result("crc proposal tracking proposal leader type", ret)
        Logger.info(
            "{} crc proposal tracking proposal leader on success!".format(
                self.tag))
        self.owner_private_key = new_leader_private_key

        # finalized
        ret = self.crc_proposal_tracking(None, CRCProposalTracking.FINALIZED,
                                         3)
        self.get_current_height()
        self.check_result("crc proposal tracking finalized type", ret)
        Logger.info("{} crc proposal tracking finalized on success!".format(
            self.tag))

        # Terminated
        # ret = self.crc_proposal_tracking(p_hash, leader_private_key, None, CRCProposalTracking.TERMINATED, 0)
        # self.get_current_height()
        # self.check_result("crc proposal tracking terminated type", ret)
        # Logger.info("{} crc proposal tracking terminated on success!".format(self.tag))

    def ready_for_crc_proposal_withdraw(self):
        ret = self.crc_proposal_withdraw()
        self.get_current_height()
        self.check_result("crc proposal withdraw", ret)
        Logger.info("{} crc proposal withdraw on success!".format(self.tag))

    def crc_proposal_withdraw(self):
        global result
        result = True

        # Recipient
        ela_node = self.node_manager.ela_nodes[1]
        recipient = ela_node.cr_account.address()

        # leader privatekey
        ela_node = self.node_manager.ela_nodes[2]
        cr_private_key = ela_node.cr_account.private_key()

        withdraw = CRCProposalWithdraw(
            private_key=cr_private_key,
            proposal_hash=self.crc_proposal_hash,
        )
        Logger.info("{} create crc proposal withdraw on success. \n{}".format(
            self.tag, withdraw))

        amount = self.get_withdraw_amount(
            util.bytes_reverse(self.crc_proposal_hash).hex()) - util.TX_FEE
        ret = self.tx_manager.crc_proposal_withdraw(
            input_address=self.CRC_COMMITTEE_ADDRESS,
            amount=amount,
            crc_proposal_withdraw=withdraw,
            output_address=recipient)
        if not ret:
            return False
        self.discrete_miner(1)
        return result

    def crc_proposal_review(self):
        global result
        result = True
        for i in range(1, self.params.ela_params.crc_number + 1):
            ela_node = self.node_manager.ela_nodes[i]
            cr_private_key = ela_node.cr_account.private_key()
            review = CRCProposalReview(private_key=cr_private_key,
                                       proposal_hash=self.crc_proposal_hash,
                                       vote_result=CRCProposalReview.APPROVE,
                                       opinion_hash=Random.get_random_bytes(
                                           serialize.UINT256SIZE))
            Logger.info(
                "{} create crc proposal review on success. \n{}".format(
                    self.tag, review))
            ret = self.tx_manager.crc_proposal_review(
                input_private_key=self.tap_account.private_key(),
                amount=10 * constant.TO_SELA,
                crc_proposal_review=review)
            if not ret:
                return False
            self.discrete_miner(1)
            Logger.info("{} node-{} review on success!\n".format(self.tag, i))
        return result

    def crc_proposal_tracking(self, new_leader_private_key, tracking_type: int,
                              stage: int):
        global result
        result = True
        tracking = CRCProposalTracking(
            secretary_private_key=self.secretary_private_key,
            leader_private_key=self.owner_private_key,
            new_leader_private_key=new_leader_private_key,
            proposal_hash=self.crc_proposal_hash,
            document_hash=Random.get_random_bytes(serialize.UINT256SIZE),
            stage=stage,
            tracking_type=tracking_type,
            secretary_opinion_hash=Random.get_random_bytes(
                serialize.UINT256SIZE),
        )
        Logger.info("{} create crc proposal tracking on success. \n{}".format(
            self.tag, tracking))
        ret = self.tx_manager.crc_proposal_tracking(
            input_private_key=self.tap_account.private_key(),
            amount=10 * constant.TO_SELA,
            crc_proposal_tracking=tracking)
        if not ret:
            return False
        self.discrete_miner(1)
        return result

    def crc_proposal_secretary_general(self):
        ela_node = self.node_manager.ela_nodes[1]
        cr_private_key = ela_node.cr_account.private_key()
        ela_node = self.node_manager.ela_nodes[2]
        secretary_general_private_key = ela_node.cr_account.private_key()

        result = True
        crc_proposal = CRCProposal(
            private_key=cr_private_key,
            cr_private_key=cr_private_key,
            secretary_general_private_key=secretary_general_private_key,
            proposal_type=CRCProposal.SECRETARY_GENERAL,
            category_data="",
            draft_hash=Random.get_random_bytes(serialize.UINT256SIZE))
        Logger.info(
            "{} create crc proposal change secretary general on success. \n{}".
            format(self.tag, crc_proposal))

        ret = self.tx_manager.crc_proposal(
            input_private_key=self.tap_account.private_key(),
            amount=10 * constant.TO_SELA,
            crc_proposal=crc_proposal)
        if not ret:
            return False
        self.discrete_miner(1)
        return result

    def crc_proposal_change_owner(self):
        ela_node = self.node_manager.ela_nodes[1]
        cr_private_key = ela_node.cr_account.private_key()
        ela_node = self.node_manager.ela_nodes[2]
        new_owner_private_key = ela_node.cr_account.private_key()
        result = True
        crc_proposal = CRCProposal(
            private_key=cr_private_key,
            cr_private_key=cr_private_key,
            new_owner_private_key=new_owner_private_key,
            proposal_type=CRCProposal.CHANGE_SPONSOR_OWNER,
            category_data="",
            draft_hash=Random.get_random_bytes(serialize.UINT256SIZE),
            target_proposal_hash=self.crc_proposal_hash)
        Logger.info(
            "{} create crc proposal change owner on success. \n{}".format(
                self.tag, crc_proposal))

        ret = self.tx_manager.crc_proposal(
            input_private_key=self.tap_account.private_key(),
            amount=10 * constant.TO_SELA,
            crc_proposal=crc_proposal)
        if not ret:
            return False
        self.discrete_miner(1)
        return result

    def crc_proposal(self):
        ela_node = self.node_manager.ela_nodes[1]
        cr_private_key = ela_node.cr_account.private_key()
        self.owner_private_key = cr_private_key
        budget_list = list()
        budget_list.append(
            Budget(budget_type=Budget.IMPREST, stage=0, amount=100000))
        budget_list.append(
            Budget(budget_type=Budget.NORMAL_PAYMENT, stage=1, amount=200000))
        budget_list.append(
            Budget(budget_type=Budget.NORMAL_PAYMENT, stage=2, amount=300000))
        budget_list.append(
            Budget(budget_type=Budget.FINAL_PAYMENT, stage=3, amount=400000))
        result = True
        crc_proposal = CRCProposal(
            private_key=cr_private_key,
            cr_private_key=cr_private_key,
            proposal_type=CRCProposal.NORMAL,
            category_data="",
            draft_hash=Random.get_random_bytes(serialize.UINT256SIZE),
            budget=budget_list,
            recipient=bytes.fromhex(ela_node.cr_account.program_hash()))
        Logger.info("{} create crc proposal on success. \n{}".format(
            self.tag, crc_proposal))

        ret = self.tx_manager.crc_proposal(
            input_private_key=self.tap_account.private_key(),
            amount=10 * constant.TO_SELA,
            crc_proposal=crc_proposal)
        self.crc_proposal_hash = crc_proposal.hash
        if not ret:
            return False
        self.discrete_miner(1)
        return result

    def register_cr_candidates(self):

        global result
        result = True
        for i in range(1, self.params.ela_params.crc_number + 1):
            ela_node = self.node_manager.ela_nodes[i]
            cid = ela_node.cr_account.cid_address()
            cr_info = self.create_cr_info(
                register_private_key=ela_node.cr_account.private_key(),
                nickname="CR-00{}".format(i),
                url="www.00{}.com".format(i),
                location=0)
            ret = self.tx_manager.register_cr(
                input_private_key=self.tap_account.private_key(),
                amount=5000 * constant.TO_SELA,
                cr_info=cr_info)
            if not ret:
                return False
            self.discrete_miner(7)
            status = self.get_cr_status(cid)
            Logger.debug(
                "After mining 7 blocks, register status: {}".format(status))
            result = status == "Active"
            if not result:
                Logger.error("{} register CR {} failed".format(
                    self.tag, ela_node.name))
                break
            Logger.info("{} register CR-{} to be a CR on success!\n".format(
                self.tag, i))

        return result

    def create_cr_info(self, register_private_key: str, nickname: str,
                       url: str, location: int):
        cr_info = CRInfo(private_key=register_private_key,
                         nickname=nickname,
                         url=url,
                         location=location)
        Logger.info("{} create cr_info on success. \n{}".format(
            self.tag, cr_info))
        return cr_info

    def register_a_cr(self, input_private_key: str, cr_info: CRInfo):
        ret = self.tx_manager.register_cr(input_private_key=input_private_key,
                                          amount=5000 * constant.TO_SELA,
                                          cr_info=cr_info)

        self.check_result("register a cr", ret)

        return ret

    def create_crc_proposal(self, register_private_key: str, nickname: str,
                            url: str, location: int):
        cr_info = CRInfo(private_key=register_private_key,
                         nickname=nickname,
                         url=url,
                         location=location)
        Logger.info("{} create create_crc_proposal on success. \n{}".format(
            self.tag, cr_info))
        return cr_info

    def create_crc_proposal_review(self, register_private_key: str,
                                   nickname: str, url: str, location: int):
        cr_info = CRInfo(private_key=register_private_key,
                         nickname=nickname,
                         url=url,
                         location=location)
        Logger.info(
            "{} create create_crc_proposal_review on success. \n{}".format(
                self.tag, cr_info))
        return cr_info

    def create_crc_tracking(self, register_private_key: str, nickname: str,
                            url: str, location: int):
        cr_info = CRInfo(private_key=register_private_key,
                         nickname=nickname,
                         url=url,
                         location=location)
        Logger.info("{} create create_crc_tracking on success. \n{}".format(
            self.tag, cr_info))
        return cr_info

    def mining_blocks_ready(self, foundation_address):
        time.sleep(3)
        rpc.discrete_mining(110)
        balance = rpc.get_balance_by_address(foundation_address)
        Logger.debug("{} foundation address value: {}".format(
            self.tag, balance))

    def check_params(self):
        if self.params.ela_params.number < 3 * self.params.ela_params.crc_number + \
                self.params.ela_params.later_start_number:
            Logger.error(
                "Ela node number should be >= 3 * crc number + later start number , "
                "please check your config in the beginning of your test case or config.json, exit..."
            )
            time.sleep(1)
            exit(-1)

    def get_arbiter_names(self, category: str):
        arbiters = rpc.get_arbiters_info()[category]
        current_nicknames = list()
        for public_key in arbiters:
            current_nicknames.append(
                self.node_manager.node_pubkey_name_dict[public_key])

        return current_nicknames

    def show_arbiter_info(self):
        arbiters_nicknames = self.get_arbiter_names("arbiters")
        arbiters_nicknames.sort()
        next_arbiter_nicknames = self.get_arbiter_names("nextarbiters")
        next_arbiter_nicknames.sort()
        Logger.info(
            "current arbiters nicknames: {}".format(arbiters_nicknames))
        Logger.info(
            "next    arbiters nicknames: {}".format(next_arbiter_nicknames))

    def reset_config(self, up_config: dict):
        for key in up_config.keys():
            if key is "side":
                if not up_config[key]:
                    self.config["arbiter"]["enable"] = False
                    self.config["did"]["enable"] = False
                    self.config["token"]["enable"] = False
                    self.config["neo"]["enable"] = False
                continue

            if key in self.node_types:
                _config = self.up_config[key]
                for k in _config.keys():
                    self.config[key][k] = _config[k]

    def terminate_all_process(self, result=True):
        Logger.info("{} terminal all the process and exit...".format(self.tag))
        self.node_manager.stop_nodes()
        time.sleep(1)
        os.system("sh {}/shell/killall.sh".format(self.root_path))
        if result:
            exit(0)

    def start_later_nodes(self):
        for node in self.later_nodes:
            node.start()

    def check_result(self, case: str, result: bool):
コード例 #8
0
class CRCProposal(Payload):
    NORMAL = 0x0000
    ELIP = 0x0100
    FLOW_ELIP = 0x0101
    INFO_ELIP = 0x0102
    MAIN_CHAIN_UPGRADE_CODE = 0x0200
    SIDE_CHAIN_UPGRADE_CODE = 0x0300
    REGISTER_SIDE_CHAIN = 0x0301
    SECRETARY_GENERAL = 0x0400
    CHANGE_SPONSOR_OWNER = 0x0401
    CLOSE_PROPOSAL = 0x0402
    DAPP_CONSENSUS = 0x0500
    WRONG = 0x4321

    def __init__(self, private_key: str, cr_private_key: str, proposal_type: int, category_data: str,
                 draft_hash: bytes, budget=None, recipient=None, target_proposal_hash=None, new_recipient=None,
                 secretary_general_private_key=None, new_owner_private_key=None):
        Payload.__init__(self, self.DEFAULT_VERSION)
        self.account = Account(private_key)
        self.cr_account = Account(cr_private_key)
        self.secretary_general_account = None
        self.new_owner_account = None
        self.proposal_type = proposal_type
        self.category_data = category_data
        self.draft_hash = draft_hash
        self.target_proposal_hash = target_proposal_hash
        self.new_owner_public_key = None
        self.budget = budget
        self.recipient = recipient
        self.new_recipient = None
        self.secretary_general_public_key = None
        self.secretary_general_did = None
        self.sign = None
        self.new_owner_signature = None
        self.secretary_general_signature = None
        self._gen_secretary_general_account(secretary_general_private_key)
        self._gen_new_owner_account(new_owner_private_key)
        self.cr_council_member_did = bytes.fromhex(self.cr_account.did())
        self.cr_council_member_sign = None
        self._gen_signature()
        self.hash = self.gen_hash()
        self.serialize_data = None

    def data(self, version: int):
        if self.serialize_data is not None:
            return self.serialize_data
        r = b""
        r = self.serialize(r, self.version)
        self.serialize_data = r
        return r

    def serialize(self, r: bytes, version: int):
        if self.proposal_type is self.SECRETARY_GENERAL:
            return self.serialize_secretary_general(r, version)
        elif self.proposal_type is self.CHANGE_SPONSOR_OWNER:
            return self.serialize_change_proposal_owner(r, version)
        elif self.proposal_type is self.CLOSE_PROPOSAL:
            return self.serialize_close_proposal(r, version)
        else:
            return self.serialize_normal_or_elip(r, version)

    def serialize_normal_or_elip(self, r: bytes, version: int):
        r = self.serialize_unsigned_normal_or_elip(r, version)
        r = serialize.write_var_bytes(r, self.sign)
        r += self.cr_council_member_did
        r = serialize.write_var_bytes(r, self.cr_council_member_sign)
        return r

    def serialize_secretary_general(self, r: bytes, version: int):
        r = self.serialize_unsigned_secretary_genera(r, version)
        r = serialize.write_var_bytes(r, self.sign)
        r = serialize.write_var_bytes(r, self.secretary_general_signature)
        r += self.cr_council_member_did
        r = serialize.write_var_bytes(r, self.cr_council_member_sign)
        return r

    def serialize_change_proposal_owner(self, r: bytes, version: int):
        r = self.serialize_unsigned_change_proposal_owner(r, version)
        r = serialize.write_var_bytes(r, self.sign)
        r = serialize.write_var_bytes(r, self.new_owner_signature)
        r += self.cr_council_member_did
        r = serialize.write_var_bytes(r, self.cr_council_member_sign)
        return r

    def serialize_close_proposal(self, r: bytes, version: int):
        r = self.serialize_unsigned_close_proposal(r, version)
        r = serialize.write_var_bytes(r, self.sign)
        r += self.cr_council_member_did
        r = serialize.write_var_bytes(r, self.cr_council_member_sign)
        return r

    def serialize_unsigned_normal_or_elip(self, r: bytes, version=0):
        r += struct.pack("<H", self.proposal_type)
        r = serialize.write_var_bytes(r, bytes(self.category_data.encode()))
        r = serialize.write_var_bytes(r, bytes.fromhex(self.account.public_key()))
        r += self.draft_hash
        r += serialize.write_var_uint(len(self.budget))
        for budget in self.budget:
            r += budget.serialize(version)
        r += self.recipient
        return r

    def serialize_unsigned_secretary_genera(self, r: bytes, version=0):
        r += struct.pack("<H", self.proposal_type)
        r = serialize.write_var_bytes(r, bytes(self.category_data.encode()))
        r = serialize.write_var_bytes(r, bytes.fromhex(self.account.public_key()))
        r += self.draft_hash
        r = serialize.write_var_bytes(r, self.secretary_general_public_key)
        r += self.secretary_general_did
        return r

    def serialize_unsigned_change_proposal_owner(self, r: bytes, version=0):
        r += struct.pack("<H", self.proposal_type)
        r = serialize.write_var_bytes(r, bytes(self.category_data.encode()))
        r = serialize.write_var_bytes(r, bytes.fromhex(self.account.public_key()))
        r += self.draft_hash
        r += self.target_proposal_hash
        r += self.new_recipient
        r = serialize.write_var_bytes(r, self.new_owner_public_key)
        return r

    def serialize_unsigned_close_proposal(self, r: bytes, version=0):
        r += struct.pack("<H", self.proposal_type)
        r = serialize.write_var_bytes(r, bytes(self.category_data.encode()))
        r = serialize.write_var_bytes(r, bytes.fromhex(self.account.public_key()))
        r += self.draft_hash
        r += self.target_proposal_hash
        return r

    def deserialize(self, r: bytes, version: int):
        pass

    def _gen_secretary_general_account(self, private_key):
        if private_key is not None:
            self.secretary_general_account = Account(private_key)
            self.secretary_general_public_key = bytes.fromhex(self.secretary_general_account.public_key())
            self.secretary_general_did = bytes.fromhex(self.secretary_general_account.did())

    def _gen_new_owner_account(self, private_key):
        if private_key is not None:
            self.new_owner_account = Account(private_key)
            self.new_owner_public_key = bytes.fromhex(self.new_owner_account.public_key())
            self.new_recipient = bytes.fromhex(self.new_owner_account.did())

    def get_deposit_address(self):
        return self.account.deposit_address()

    def _gen_signature(self):
        r = b""
        if self.proposal_type is self.SECRETARY_GENERAL:
            r = self.serialize_unsigned_secretary_genera(r, self.version)
            self.sign = keytool.ecdsa_sign(bytes.fromhex(self.account.private_key()), r)
            self.secretary_general_signature = keytool.ecdsa_sign(
                bytes.fromhex(self.secretary_general_account.private_key()), r)
            r = serialize.write_var_bytes(r, self.sign)
            r = serialize.write_var_bytes(r, self.secretary_general_signature)
            r += self.cr_council_member_did
            self.cr_council_member_sign = keytool.ecdsa_sign(bytes.fromhex(self.cr_account.private_key()), r)
            return r
        elif self.proposal_type is self.CHANGE_SPONSOR_OWNER:
            r = self.serialize_unsigned_change_proposal_owner(r, self.version)
            self.sign = keytool.ecdsa_sign(bytes.fromhex(self.account.private_key()), r)
            self.new_owner_signature = keytool.ecdsa_sign(bytes.fromhex(self.new_owner_account.private_key()), r)
            r = serialize.write_var_bytes(r, self.sign)
            r = serialize.write_var_bytes(r, self.new_owner_signature)
            r += self.cr_council_member_did
            self.cr_council_member_sign = keytool.ecdsa_sign(bytes.fromhex(self.cr_account.private_key()), r)
            return r
        elif self.proposal_type is self.CLOSE_PROPOSAL:
            r = self.serialize_unsigned_close_proposal(r, self.version)
            self.sign = keytool.ecdsa_sign(bytes.fromhex(self.account.private_key()), r)
            r = serialize.write_var_bytes(r, self.sign)
            r += self.cr_council_member_did
            self.cr_council_member_sign = keytool.ecdsa_sign(bytes.fromhex(self.cr_account.private_key()), r)
            return r
        else:
            r = self.serialize_unsigned_normal_or_elip(r, self.version)
            self.sign = keytool.ecdsa_sign(bytes.fromhex(self.account.private_key()), r)
            r = serialize.write_var_bytes(r, self.sign)
            r += self.cr_council_member_did
            self.cr_council_member_sign = keytool.ecdsa_sign(bytes.fromhex(self.cr_account.private_key()), r)
            return r

    def gen_hash(self):
        r = b""
        r = self.serialize(r, 0)
        return keytool.sha256_hash(r, 2)

    def __repr__(self):
        if self.proposal_type is self.SECRETARY_GENERAL:
            return "CRCProposalSecretaryGeneral {" + "\n\t" \
                   + "privateKey: {}".format(self.proposal_type) + "\n\t" \
                   + "crCouncilMemberDid: {}".format(self.proposal_type) + "\n\t" \
                   + "proposalType: {}".format(self.proposal_type) + "\n\t" \
                   + "categoryData : {}".format(self.category_data) + "\n\t" \
                   + "sponsorPublicKey : {}".format(self.account.public_key()) + "\n\t" \
                   + "draftHash: {}".format(self.draft_hash.hex()) + "\n\t" \
                   + "secretaryGeneralPublicKey: {}".format(self.secretary_general_public_key.hex()) + "\n\t" \
                   + "secretaryGeneralDid: {}".format(keytool.create_address(self.secretary_general_did)) + "\n\t" \
                   + "sign: {}".format(self.sign.hex()) + "\n\t" \
                   + "secretaryGeneralSignature: {}".format(self.secretary_general_signature.hex()) + "\n\t" \
                   + "crCouncilMemberDid: {}".format(keytool.create_address(self.cr_council_member_did)) + "\n\t" \
                   + "crCouncilMemberSign: {}".format(self.cr_council_member_sign.hex()) + "\n\t" \
                   + "hash: {}".format(self.hash.hex()) + "\n\t" \
                   + "}"
        elif self.proposal_type is self.CHANGE_SPONSOR_OWNER:
            return "CRCProposalChangeSponsor {" + "\n\t" \
                   + "proposalType: {}".format(self.proposal_type) + "\n\t" \
                   + "categoryData : {}".format(self.category_data) + "\n\t" \
                   + "sponsorPublicKey : {}".format(self.account.public_key()) + "\n\t" \
                   + "draftHash: {}".format(self.draft_hash.hex()) + "\n\t" \
                   + "targetProposalHash: {}".format(self.target_proposal_hash.hex()) + "\n\t" \
                   + "newRecipient: {}".format(keytool.create_address(self.new_recipient)) + "\n\t" \
                   + "newOwnerPublicKey: {}".format(self.new_owner_public_key.hex()) + "\n\t" \
                   + "sign: {}".format(self.sign.hex()) + "\n\t" \
                   + "crCouncilMemberDid: {}".format(keytool.create_address(self.cr_council_member_did)) + "\n\t" \
                   + "crCouncilMemberSign: {}".format(self.cr_council_member_sign.hex()) + "\n\t" \
                   + "hash: {}".format(self.hash.hex()) + "\n\t" \
                   + "}"
        elif self.proposal_type is self.CLOSE_PROPOSAL:
            return "CRCProposalCloseProposal {" + "\n\t" \
                   + "proposalType: {}".format(self.proposal_type) + "\n\t" \
                   + "categoryData : {}".format(self.category_data) + "\n\t" \
                   + "sponsorPublicKey : {}".format(self.account.public_key()) + "\n\t" \
                   + "draftHash: {}".format(self.draft_hash.hex()) + "\n\t" \
                   + "targetProposalHash: {}".format(self.target_proposal_hash.hex) + "\n\t" \
                   + "sign: {}".format(self.sign.hex()) + "\n\t" \
                   + "crCouncilMemberDid: {}".format(keytool.create_address(self.cr_council_member_did)) + "\n\t" \
                   + "crCouncilMemberSign: {}".format(self.cr_council_member_sign.hex()) + "\n\t" \
                   + "hash: {}".format(self.hash.hex()) + "\n\t" \
                   + "}"
        else:
            return "CRCProposal {" + "\n\t" \
                   + "proposalType: {}".format(self.proposal_type) + "\n\t" \
                   + "categoryData : {}".format(self.category_data) + "\n\t" \
                   + "sponsorPublicKey : {}".format(self.account.public_key()) + "\n\t" \
                   + "draftHash: {}".format(self.draft_hash.hex()) + "\n\t" \
                   + "budgets: {}".format(self.budget) + "\n\t" \
                   + "recipient: {}".format(keytool.create_address(self.recipient)) + "\n\t" \
                   + "sign: {}".format(self.sign.hex()) + "\n\t" \
                   + "crCouncilMemberDid: {}".format(keytool.create_address(self.cr_council_member_did)) + "\n\t" \
                   + "crCouncilMemberSign: {}".format(self.cr_council_member_sign.hex()) + "\n\t" \
                   + "hash: {}".format(self.hash.hex()) + "\n\t" \
                   + "}"
コード例 #9
0
class TxControl(object):
    PRODUCER_STATE_ACTIVE = "Active"
    PRODUCER_STATE_INACTIVE = "Inactive"

    # CR_Foundation_TEMP = "EULhetag9FKS6Jd6aifFaPqjFTpZbSMY7u"
    CR_Foundation_TEMP = "CRASSETSXXXXXXXXXXXXXXXXXXXX2qDX5J"
    SECRETARY_PRIVATE_KEY = "E0076A271A137A2BD4429FA46E79BE3E10F2A730585F8AC2763D570B60469F11"
    CRC_COMMITTEE_ADDRESS = "CREXPENSESXXXXXXXXXXXXXXXXXX4UdT6b"

    def __init__(self, config: dict):
        self.tag = util.tag_from_path(__file__, TxControl.__name__)
        self._init_config(config)
        self.tap_account = Account(private_key_str=self.tap_private_key)
        self.pressure_account = Account(
            private_key_str=self.pressure_private_key)
        self.register_amount = 6000
        self.node_amount = 5000
        self.dpos_votes_dict = dict()
        self.producers_list = list()
        self.cr_list = list()
        self.tx_manager = TxManager(self.rpc_port)

    def _init_config(self, config: dict):
        self.rpc_port = config["rpc_port"]
        self.host = config["host"]
        self.outputs_num = config["outputs_num"]
        self.inputs_num = config["inputs_num"]
        self.block_size = config["block_size"]
        self.pressure_private_key = config["pressure_private_key"]
        self.tap_private_key = config["tap_private_key"]
        self.lock_address = config["lock_address"]
        self.recharge = config["recharge"]
        self.eth_tap_address = config["eth_tap_address"]
        rpc.DEFAULT_HOST = self.host

    def ready_for_pressure_outputs(self):
        ret = self.pressure_outputs()
        self.check_result(
            "pressure outputs number:{}".format(self.outputs_num), ret)
        Logger.info("{}pressure outputs on success!".format(self.tag))

    def ready_for_pressure_inputs(self):
        ret = self.pressure_inputs()
        self.check_result("pressure inputs number:{}".format(self.inputs_num),
                          ret)
        Logger.info("{}pressure inputs on success!".format(self.tag))

    def ready_for_pressure_cross_chain(self):
        Logger.info("waiting for cross chain pressure test ... ")
        ret = self.pressure_cross_chain()
        self.check_result(
            "pressure cross chain number:{}".format(self.outputs_num), ret)
        Logger.info("{}pressure cross chain on success!".format(self.tag))

    def ready_for_pressure_big_block(self):
        ret = self.pressure_big_block()
        self.check_result(
            "pressure big block size:{} ".format(self.block_size), ret)
        Logger.info("{}pressure big block on success!".format(
            self.tag, self.block_size))

    def pressure_outputs(self):
        output_addresses = list()
        for i in range(self.outputs_num):
            output_addresses.append(self.pressure_account.address())
        ret = self.tx_manager.transfer_asset(self.tap_account.private_key(),
                                             output_addresses,
                                             util.TX_SINGLE_OUTPUT,
                                             not self.recharge)
        if ret:
            self.wait_block()
            return True
        else:
            Logger.error("{} pressure outputs transfer failed".format(
                self.tag))
            return False

    def pressure_inputs(self):

        value = self.inputs_num * util.TX_FEE
        Logger.debug("{} account {} wallet balance: {}".format(
            self.tag, self.pressure_account.address(), value))

        ret = self.tx_manager.transfer_asset(
            self.pressure_account.private_key(), [self.tap_account.address()],
            value - util.TX_FEE)
        if ret:
            self.wait_block()
            return True
        else:
            Logger.error("{} pressure inputs transfer failed".format(self.tag))
            return False

    def pressure_cross_chain(self):

        value = self.outputs_num * util.TX_SINGLE_OUTPUT
        Logger.info("{} account {} wallet balance: {}".format(
            self.tag, self.pressure_account.address(), value))

        #self.tap_account.address(),
        #"0x53781e106a2e3378083bdcede1874e5c2a7225f8",
        ret = self.tx_manager.transfer_multi_cross_chain_asset(
            self.pressure_account.private_key(), self.lock_address,
            self.eth_tap_address, self.outputs_num,
            util.TX_SINGLE_OUTPUT - util.TX_FEE, self.recharge, self.rpc_port)
        if ret:
            self.wait_block()
            return True
        else:
            Logger.error("{} pressure inputs transfer failed".format(self.tag))
            return False

    def pressure_big_block(self):
        attributes = list()
        attribute = Attribute(usage=Attribute.NONCE,
                              data=Random.get_random_bytes(self.block_size))
        attributes.append(attribute)
        ret = self.tx_manager.transfer_abnormal_asset(
            self.tap_account.private_key(), [self.tap_account.address()],
            1 * util.TO_SELA,
            attributes=attributes)
        if ret:
            self.wait_block()
            return True
        else:
            Logger.error("{} pressure big block transfer failed".format(
                self.tag))
            return False

    def ready_for_dpos(self):
        producers = rpc.list_producers(0, 100, state="active")
        if producers is None:
            Logger.info('{} list producers is null'.format(self.tag))
            return
        Logger.debug('{} list producers:{}'.format(self.tag, producers))
        self.producers_list = producers["producers"]
        ret = self.vote_producers_candidates()
        self.check_result("vote producers", ret)
        Logger.info("{} vote producer on success!".format(self.tag))
        # self.get_dpos_votes()

    def ready_for_cr(self):
        cr = rpc.list_current_crs()
        # cr = rpc.list_cr_candidates(0, 100, state="active")
        if cr is None:
            Logger.info('{} list cr is null'.format(self.tag))
            return
        Logger.debug('{} list cr:{}'.format(self.tag, cr))
        # self.cr_list = cr["crcandidatesinfo"]
        self.cr_list = cr["crmembersinfo"]
        ret = self.vote_cr_candidates()
        self.check_result("vote cr", ret)
        Logger.info("{} vote cr on success!".format(self.tag))

    def ready_for_crc_proposal(self):
        ret, p_hash = self.crc_proposal()
        self.get_current_height()
        self.check_result("crc proposal", ret)
        Logger.info("{} crc proposal on success!".format(self.tag))
        return p_hash

    def ready_for_crc_proposal_review(self, p_hash: bytes):
        ret = self.crc_proposal_review(p_hash)
        self.get_current_height()
        self.check_result("crc proposal review", ret)
        Logger.info("{} crc proposal review on success!".format(self.tag))
        self.discrete_miner(self.params.ela_params.proposal_cr_voting_period)

        ret = self.tx_manager.vote_crc_proposal_candidates()
        self.get_current_height()
        self.check_result("vote cr proposal", ret)
        Logger.info("{} vote crc proposal  on success!".format(self.tag))
        self.discrete_miner(
            self.params.ela_params.proposal_public_voting_period)

    def ready_for_crc_proposal_tracking(self, p_hash: bytes):
        ela_node = self.node_manager.ela_nodes[1]
        leader_private_key = ela_node.cr_account.private_key()
        # common
        ret = self.crc_proposal_tracking(p_hash, leader_private_key, None,
                                         CRCProposalTracking.COMMON, 0)
        self.get_current_height()
        self.check_result("crc proposal tracking common type", ret)
        Logger.info("{} crc proposal tracking common on success!".format(
            self.tag))

        # progress
        ret = self.crc_proposal_tracking(p_hash, leader_private_key, None,
                                         CRCProposalTracking.PROGRESS, 1)
        self.get_current_height()
        self.check_result("crc proposal tracking progress type", ret)
        Logger.info("{} crc proposal tracking progress on success!".format(
            self.tag))

        # Reject
        ret = self.crc_proposal_tracking(p_hash, leader_private_key, None,
                                         CRCProposalTracking.REJECTED, 2)
        self.get_current_height()
        self.check_result("crc proposal tracking reject type", ret)
        Logger.info("{} crc proposal tracking reject on success!".format(
            self.tag))

        # progress
        ret = self.crc_proposal_tracking(p_hash, leader_private_key, None,
                                         CRCProposalTracking.PROGRESS, 2)
        self.get_current_height()
        self.check_result("crc proposal tracking progress type", ret)
        Logger.info("{} crc proposal tracking progress on success!".format(
            self.tag))

        # proposal leader
        ela_node = self.node_manager.ela_nodes[2]
        new_leader_private_key = ela_node.cr_account.private_key()
        ret = self.crc_proposal_tracking(p_hash, leader_private_key,
                                         new_leader_private_key,
                                         CRCProposalTracking.PROPOSAL_LEADER,
                                         0)
        self.get_current_height()
        self.check_result("crc proposal tracking proposal leader type", ret)
        Logger.info(
            "{} crc proposal tracking proposal leader on success!".format(
                self.tag))

        # finalized
        ret = self.crc_proposal_tracking(p_hash, new_leader_private_key, None,
                                         CRCProposalTracking.FINALIZED, 3)
        self.get_current_height()
        self.check_result("crc proposal tracking finalized type", ret)
        Logger.info("{} crc proposal tracking finalized on success!".format(
            self.tag))

        # Terminated
        # ret = self.crc_proposal_tracking(p_hash, leader_private_key, None, CRCProposalTracking.TERMINATED, 0)
        # self.get_current_height()
        # self.check_result("crc proposal tracking terminated type", ret)
        # Logger.info("{} crc proposal tracking terminated on success!".format(self.tag))

    def ready_for_crc_proposal_withdraw(self, p_hash: bytes):
        ret = self.crc_proposal_withdraw(p_hash)
        self.get_current_height()
        self.check_result("crc proposal withdraw", ret)
        Logger.info("{} crc proposal withdraw on success!".format(self.tag))

    def crc_proposal_withdraw(self, p_hash: bytes):
        global result
        result = True

        # Recipient
        ela_node = self.node_manager.ela_nodes[1]
        recipient = ela_node.cr_account.address()

        # leader privatekey
        ela_node = self.node_manager.ela_nodes[2]
        cr_private_key = ela_node.cr_account.private_key()

        withdraw = CRCProposalWithdraw(
            private_key=cr_private_key,
            proposal_hash=p_hash,
        )
        Logger.info("{} create crc proposal withdraw on success. \n{}".format(
            self.tag, withdraw))

        amount = self.get_withdraw_amount(p_hash.hex()) - util.TX_FEE
        ret = self.tx_manager.crc_proposal_withdraw(
            input_address=self.CRC_COMMITTEE_ADDRESS,
            amount=amount,
            crc_proposal_withdraw=withdraw,
            output_address=recipient)
        if not ret:
            return False
        self.discrete_miner(1)
        return result

    def crc_proposal_review(self, p_hash: bytes):
        global result
        result = True
        for i in range(1, self.params.ela_params.crc_number + 1):
            ela_node = self.node_manager.ela_nodes[i]
            cr_private_key = ela_node.cr_account.private_key()
            review = CRCProposalReview(private_key=cr_private_key,
                                       proposal_hash=p_hash,
                                       vote_result=CRCProposalReview.APPROVE,
                                       opinion_hash=Random.get_random_bytes(
                                           serialize.UINT256SIZE))
            Logger.info(
                "{} create crc proposal review on success. \n{}".format(
                    self.tag, review))
            ret = self.tx_manager.crc_proposal_review(
                input_private_key=self.tap_account.private_key(),
                amount=10 * constant.TO_SELA,
                crc_proposal_review=review)
            if not ret:
                return False
            self.discrete_miner(1)
            Logger.info("{} node-{} review on success!\n".format(self.tag, i))
        return result

    def crc_proposal_tracking(self, p_hash: bytes, leader_private_key: str,
                              new_leader_private_key, tracking_type: int,
                              stage: int):
        global result
        result = True
        tracking = CRCProposalTracking(
            secretary_private_key=self.SECRETARY_PRIVATE_KEY,
            leader_private_key=leader_private_key,
            new_leader_private_key=new_leader_private_key,
            proposal_hash=p_hash,
            document_hash=Random.get_random_bytes(serialize.UINT256SIZE),
            stage=stage,
            tracking_type=tracking_type,
            secretary_opinion_hash=Random.get_random_bytes(
                serialize.UINT256SIZE),
        )
        Logger.info("{} create crc proposal tracking on success. \n{}".format(
            self.tag, tracking))
        ret = self.tx_manager.crc_proposal_tracking(
            input_private_key=self.tap_account.private_key(),
            amount=10 * constant.TO_SELA,
            crc_proposal_tracking=tracking)
        if not ret:
            return False
        self.discrete_miner(1)
        return result

    def crc_proposal(self):
        ela_node = self.node_manager.ela_nodes[1]
        cr_private_key = ela_node.cr_account.private_key()
        budget_list = list()
        budget_list.append(
            Budget(budget_type=Budget.IMPREST, stage=0, amount=100000))
        budget_list.append(
            Budget(budget_type=Budget.NORMAL_PAYMENT, stage=1, amount=200000))
        budget_list.append(
            Budget(budget_type=Budget.NORMAL_PAYMENT, stage=2, amount=300000))
        budget_list.append(
            Budget(budget_type=Budget.FINAL_PAYMENT, stage=3, amount=400000))
        result = True
        crc_proposal = CRCProposal(
            private_key=cr_private_key,
            cr_private_key=cr_private_key,
            proposal_type=CRCProposal.NORMAL,
            category_data="normal",
            draft_hash=Random.get_random_bytes(serialize.UINT256SIZE),
            budget=budget_list,
            recipient=bytes.fromhex(ela_node.cr_account.program_hash()))
        Logger.info("{} create crc proposal on success. \n{}".format(
            self.tag, crc_proposal))

        ret = self.tx_manager.crc_proposal(
            input_private_key=self.tap_account.private_key(),
            amount=10 * constant.TO_SELA,
            crc_proposal=crc_proposal)
        if not ret:
            return False, crc_proposal.hash
        self.discrete_miner(1)
        return result, crc_proposal.hash

    def register_cr_candidates(self):

        global result
        result = True
        for i in range(1, self.params.ela_params.crc_number + 1):
            ela_node = self.node_manager.ela_nodes[i]
            cid = ela_node.cr_account.cid_address()
            cr_info = self.create_cr_info(
                register_private_key=ela_node.cr_account.private_key(),
                nickname="CR-00{}".format(i),
                url="www.00{}.com".format(i),
                location=0)
            ret = self.tx_manager.register_cr(
                input_private_key=self.tap_account.private_key(),
                amount=5000 * constant.TO_SELA,
                cr_info=cr_info)
            if not ret:
                return False
            self.discrete_miner(7)
            status = self.get_cr_status(cid)
            Logger.debug(
                "After mining 7 blocks, register status: {}".format(status))
            result = status == "Active"
            if not result:
                Logger.error("{} register CR {} failed".format(
                    self.tag, ela_node.name))
                break
            Logger.info("{} register node-{} to be a CR on success!\n".format(
                self.tag, i))

        return result

    def create_cr_info(self, register_private_key: str, nickname: str,
                       url: str, location: int):
        cr_info = CRInfo(private_key=register_private_key,
                         nickname=nickname,
                         url=url,
                         location=location)
        Logger.info("{} create cr_info on success. \n{}".format(
            self.tag, cr_info))
        return cr_info

    def register_a_cr(self, input_private_key: str, cr_info: CRInfo):
        ret = self.tx_manager.register_cr(input_private_key=input_private_key,
                                          amount=5000 * constant.TO_SELA,
                                          cr_info=cr_info)

        self.check_result("register a cr", ret)

        return ret

    def create_crc_proposal(self, register_private_key: str, nickname: str,
                            url: str, location: int):
        cr_info = CRInfo(private_key=register_private_key,
                         nickname=nickname,
                         url=url,
                         location=location)
        Logger.info("{} create create_crc_proposal on success. \n{}".format(
            self.tag, cr_info))
        return cr_info

    def create_crc_proposal_review(self, register_private_key: str,
                                   nickname: str, url: str, location: int):
        cr_info = CRInfo(private_key=register_private_key,
                         nickname=nickname,
                         url=url,
                         location=location)
        Logger.info(
            "{} create create_crc_proposal_review on success. \n{}".format(
                self.tag, cr_info))
        return cr_info

    def create_crc_tracking(self, register_private_key: str, nickname: str,
                            url: str, location: int):
        cr_info = CRInfo(private_key=register_private_key,
                         nickname=nickname,
                         url=url,
                         location=location)
        Logger.info("{} create create_crc_tracking on success. \n{}".format(
            self.tag, cr_info))
        return cr_info

    def mining_blocks_ready(self, foundation_address):
        time.sleep(3)
        rpc.discrete_mining(110)
        balance = rpc.get_balance_by_address(foundation_address)
        Logger.debug("{} foundation address value: {}".format(
            self.tag, balance))

    def check_params(self):
        if self.params.ela_params.number < 3 * self.params.ela_params.crc_number + \
                self.params.ela_params.later_start_number:
            Logger.error(
                "Ela node number should be >= 3 * crc number + later start number , "
                "please check your config in the beginning of your test case or config.json, exit..."
            )
            time.sleep(1)
            exit(-1)

    def get_arbiter_names(self, category: str):
        arbiters = rpc.get_arbiters_info()[category]
        current_nicknames = list()
        for public_key in arbiters:
            current_nicknames.append(
                self.node_manager.node_pubkey_name_dict[public_key])

        return current_nicknames

    def show_arbiter_info(self):
        arbiters_nicknames = self.get_arbiter_names("arbiters")
        arbiters_nicknames.sort()
        next_arbiter_nicknames = self.get_arbiter_names("nextarbiters")
        next_arbiter_nicknames.sort()
        Logger.info(
            "current arbiters nicknames: {}".format(arbiters_nicknames))
        Logger.info(
            "next    arbiters nicknames: {}".format(next_arbiter_nicknames))

    def reset_config(self, up_config: dict):
        for key in up_config.keys():
            if key is "side":
                if not up_config[key]:
                    self.config["arbiter"]["enable"] = False
                    self.config["did"]["enable"] = False
                    self.config["token"]["enable"] = False
                    self.config["neo"]["enable"] = False
                continue

            if key in self.node_types:
                _config = self.up_config[key]
                for k in _config.keys():
                    self.config[key][k] = _config[k]

    def vote_producers_candidates(self):
        candidates = list()
        vote_amount = 10
        p = len(self.producers_list)
        if len(self.producers_list) > 36:
            p = 36
        for i in range(1, p):
            producer = self.producers_list[i]["ownerpublickey"]
            candidates.append(
                CandidateVotes(bytes.fromhex(producer), vote_amount))
        ret = self.tx_manager.vote_producer(
            input_private_key=self.tap_private_key,
            amount=vote_amount,
            candidates=candidates,
        )
        if not ret:
            return False
        self.wait_block()
        return True

    def vote_cr_candidates(self):
        candidates = list()
        amount = 0
        p = len(self.cr_list)
        if len(self.cr_list) > 36:
            p = 36
        for i in range(1, p):
            cr = self.cr_list[i]["cid"]
            vote_amount = i * 10
            amount += vote_amount
            candidates.append(
                CandidateVotes(keytool.address_to_program_hash(cr),
                               vote_amount))
        ret = self.tx_manager.vote_cr(
            input_private_key=self.tap_account.private_key(),
            amount=amount,
            candidates=candidates,
        )
        if not ret:
            return False
        self.wait_block()
        return True

    def check_result(self, case: str, result: bool):
コード例 #10
0
class CRInfo(Payload):
    CR_INFO_VERSION = 0x00
    CR_INFO_DID_VERSION = 0x01

    def __init__(self, private_key: str, nickname: str, url: str,
                 location: int):
        Payload.__init__(self, self.DEFAULT_VERSION)
        self.account = Account(private_key)
        self.nickname = nickname
        self.url = url
        self.location = location
        self.code = self.account.redeem_script()
        self.cid = self.account.cid()
        self.did = self.account.did()
        self.signature = None
        self.gen_signature()
        self.serialize_data = None

    def data(self, version: int):
        if self.serialize_data is not None:
            return self.serialize_data
        r = b""
        r = self.serialize(r, self.version)
        self.serialize_data = r
        return r

    def serialize(self, r: bytes, version: int):
        r = self.serialize_unsigned(r, version)

        if self.signature is not None:
            r = serialize.write_var_bytes(r, self.signature)

        return r

    def serialize_unsigned(self, r: bytes, version=0):
        r = serialize.write_var_bytes(r, bytes.fromhex(self.code))
        r += bytes.fromhex(self.cid)
        r += bytes.fromhex(self.did)
        r = serialize.write_var_bytes(r, bytes(self.nickname.encode()))
        r = serialize.write_var_bytes(r, bytes(self.url.encode()))
        r += struct.pack("<Q", self.location)

        return r

    def deserialize(self, r: bytes, version: int):
        pass

    def get_deposit_address(self):
        return self.account.deposit_address()

    def gen_signature(self):
        r = b""
        r = self.serialize_unsigned(r, self.version)
        signature = keytool.ecdsa_sign(
            bytes.fromhex(self.account.private_key()), r)
        self.signature = signature
        return signature

    def __repr__(self):
        return "CRInfo {" + "\n\t" \
               + "privateKey: {}".format(self.account.private_key()) + "\n\t" \
               + "code: {}".format(self.code) + "\n\t" \
               + "cid : {}".format(keytool.create_address(bytes.fromhex(self.cid))) + "\n\t" \
               + "did : {}".format(keytool.create_address(bytes.fromhex(self.did))) + "\n\t" \
               + "nickname: {}".format(self.nickname) + "\n\t" \
               + "url: {}".format(self.url) + "\n\t" \
               + "location: {}".format(self.location) + "\n\t" \
               + "signature: {}".format(self.signature.hex()) + "\n" \
               + "}"