Beispiel #1
0
    def transfer_multi_cross_chain_asset(self, input_private_key: str,
                                         lock_address: str, cross_address: str,
                                         tx_count: int, amount: int,
                                         recharge: bool, port: int):
        account = Account(input_private_key)
        response = rpc.list_unspent_utxos(account.address(), port=port)
        if not response or isinstance(response, dict):
            Logger.error("get utxos return error: {}".format(response))
            return False
        utxos = response
        if len(utxos) < tx_count:
            Logger.error("utxo is not enough")
            return False

        for i in range(tx_count):
            current_utxos = list()
            utxo = utxos[i]
            current_utxos.append(utxo)
            Logger.info("current cross chain index: {}".format(i))
            tx = txbuild.create_cross_chain_transaction_by_utxo(
                input_private_key=input_private_key,
                lock_address=lock_address,
                cross_chain_address=cross_address,
                amount=amount,
                recharge=recharge,
                utxos=current_utxos)

            if tx is None:
                return False

            tx = txbuild.single_sign_transaction(input_private_key, tx)
            Logger.debug("cross chain asset transaction: \n{}".format(tx))
            ret = self.handle_tx_result(tx, port)

        return ret
Beispiel #2
0
 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
Beispiel #3
0
 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 __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
Beispiel #5
0
 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
Beispiel #6
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" \
               + "}"
Beispiel #7
0
 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 create_transaction(input_private_key: str, output_addresses: list, amount: int, rpc_port: int, side_chain: bool):
    account = Account(input_private_key)
    # check output
    if output_addresses is None or len(output_addresses) == 0:
        Logger.error("Invalid output addresses")
        return None

    # create outputs
    outputs, total_amount = create_normal_outputs(
        output_addresses=output_addresses,
        amount=amount,
        fee=util.TX_FEE,
        output_lock=0
    )

    # create inputs
    inputs, change_outputs = create_normal_inputs(account.address(), total_amount, rpc_port)

    if inputs is None or change_outputs is None:
        Logger.error("Create normal inputs failed")
        return None
    outputs.extend(change_outputs)

    # create program
    programs = list()
    redeem_script = bytes.fromhex(account.redeem_script())
    program = Program(code=redeem_script, params=None)
    programs.append(program)

    # create attributes
    attributes = list()
    attribute = Attribute(
        usage=Attribute.NONCE,
        data=bytes("attributes".encode())
    )
    attributes.append(attribute)

    tx = Transaction()
    if not side_chain :
        tx.version = Transaction.TX_VERSION_09
    else:
        tx.version = Transaction.TX_VERSION_DEFAULT

    tx.tx_type = Transaction.TRANSFER_ASSET
    tx.payload = Payload(Payload.DEFAULT_VERSION)
    tx.attributes = attributes
    tx.inputs = inputs
    tx.outputs = outputs
    tx.lock_time = 0
    tx.programs = programs

    return tx
    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
 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
Beispiel #11
0
    def __init__(self, input_private_key: str, node: ElaNode, nick_name: str,
                 url: str, location: int, net_address: str):

        self.input_private_key = input_private_key
        self.input = Account(input_private_key)
        self.node = node
        self.utxo_value = 0
        self.fee = 10000
        self.state = ""
        self.deposit_amount = 5000 * util.TO_SELA
        self.info = self._producer_info(self.node.owner_account,
                                        self.node.node_account, nick_name, url,
                                        location, net_address)
def create_vote_transaction(input_private_key: str, candidates_list: list, amount: int, rpc_port: int, vote_content):
    # check output
    if candidates_list is None or len(candidates_list) == 0:
        Logger.error("Invalid output addresses")
        return None

    # candidates_bytes_list = list()
    #
    # for candidate in candidates_list:
    #     candidates_bytes_list.append(bytes.fromhex(candidate))

    # create outputs
    account = Account(input_private_key)
    outputs = create_vote_output(account.address(), amount, vote_content)

    # create inputs
    total_amount = amount + util.TX_FEE
    inputs, change_outputs = create_normal_inputs(account.address(), total_amount, rpc_port)
    if inputs is None or change_outputs is None:
        Logger.error("Create normal inputs failed")
        return None
    outputs.extend(change_outputs)

    # create program
    programs = list()
    redeem_script = bytes.fromhex(account.redeem_script())
    program = Program(code=redeem_script, params=None)
    programs.append(program)

    # create attributes
    attributes = list()
    attribute = Attribute(
        usage=Attribute.NONCE,
        data=bytes("attributes".encode())
    )
    attributes.append(attribute)

    tx = Transaction()
    tx.version = Transaction.TX_VERSION_09
    tx.tx_type = Transaction.TRANSFER_ASSET
    tx.payload = Payload(Payload.DEFAULT_VERSION)
    tx.attributes = attributes
    tx.inputs = inputs
    tx.outputs = outputs
    tx.lock_time = 0
    tx.programs = programs

    return tx
Beispiel #13
0
def test_content():

    test_case = "update producer after pre offset but before h2"

    controller = Controller(config)
    controller.ready_for_dpos()
    h1 = controller.params.ela_params.crc_dpos_height
    h2 = controller.params.ela_params.public_dpos_height
    pre_offset = config["ela"]["pre_connect_offset"]

    update_node_prikey = "aa8ad6d1ac6953f7b9a68b5b13fe79d7217fb687651c1c30be12e5e0328b667f"
    # update_producer_beforeh1 = controller.tx_manager.register_producers_list[0]
    update_producer = controller.tx_manager.register_producers_list[0]
    current_height = controller.get_current_height()
    if current_height < h1 - 5:
        controller.discrete_mining_blocks(h1 - 5 - current_height)

    height_times = dict()
    height_times[current_height] = 1

    global result
    global update_height
    update_height = 0

    while True:
        current_height = controller.get_current_height()
        times = controller.get_height_times(height_times, current_height)
        Logger.debug("current height: {}, times: {}".format(
            current_height, times))

        if times >= 100:
            result = False
            break
        if current_height >= h1:
            controller.show_arbiter_info()

        if update_height == 0 and current_height > h1 + 35:
            producer_payload = update_producer.producer_info()
            producer_payload.nickname = "^_^ HAHA"
            producer_payload.node_account = Account(update_node_prikey)

            producer_payload.url = "127.0.0.1"

            result = controller.tx_manager.update_producer(
                update_producer, producer_payload)
            controller.check_result(test_case, result)
            if result:
                controller.node_manager.node_pubkey_name_dict[
                    update_node_prikey] = producer_payload.nickname
            update_height = current_height

        if current_height > h2 + 100:
            break

        controller.discrete_mining_blocks(1)
        time.sleep(1)

    controller.check_result(test_case, result)
    controller.terminate_all_process(result)
def create_crc_proposal_tracking_transaction(input_private_key: str, amount: int, payload: CRCProposalTracking,
                                             rpc_port: int):
    # create outputs
    account = Account(input_private_key)
    outputs, total_amount = create_normal_outputs(
        output_addresses=[account.address()],
        amount=amount,
        fee=util.TX_FEE,
        output_lock=0
    )

    # create inputs
    inputs, change_outputs = create_normal_inputs(account.address(), total_amount, rpc_port)
    if inputs is None or change_outputs is None:
        Logger.error("Create normal inputs failed")
        return None
    outputs.extend(change_outputs)

    # create program
    programs = list()
    redeem_script = bytes.fromhex(account.redeem_script())
    program = Program(code=redeem_script, params=None)
    programs.append(program)

    # create attributes
    attributes = list()
    attribute = Attribute(
        usage=Attribute.NONCE,
        data=bytes("attributes".encode())
    )
    attributes.append(attribute)

    tx = Transaction()
    tx.version = Transaction.TX_VERSION_09
    tx.tx_type = Transaction.CRC_PROPOSAL_TRACKING
    tx.payload_version = 0
    tx.payload = payload
    tx.attributes = attributes
    tx.inputs = inputs
    tx.outputs = outputs
    tx.lock_time = 0
    tx.programs = programs

    return tx
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" \
               + "}"
def create_cancel_transaction(input_private_key: str, payload: ProducerInfo, rpc_port: int):
    # create inputs
    account = Account(input_private_key)
    inputs, change_outputs = create_normal_inputs(account.address(), util.TX_FEE, rpc_port)
    if inputs is None or change_outputs is None:
        Logger.error("Create normal inputs failed")
        return None

    # create outputs
    outputs = list()
    outputs.extend(change_outputs)

    # create program
    programs = list()
    redeem_script = bytes.fromhex(account.redeem_script())
    program = Program(code=redeem_script, params=None)
    programs.append(program)

    # create attributes
    attributes = list()
    attribute = Attribute(
        usage=Attribute.NONCE,
        data=bytes("attributes".encode())
    )
    attributes.append(attribute)

    payload = ProcessProducer(bytes.fromhex(payload.owner_account.public_key()),
                              bytes.fromhex(payload.owner_account.private_key()))
    tx = Transaction()
    tx.version = Transaction.TX_VERSION_09
    tx.tx_type = Transaction.CANCEL_PRODUCER
    tx.payload_version = 0
    tx.payload = payload
    tx.attributes = attributes
    tx.inputs = inputs
    tx.outputs = outputs
    tx.lock_time = 0
    tx.programs = programs

    return tx
def create_cr_update_transaction(input_private_key: str, update_payload: CRInfo, rpc_port: int):
    # create inputs
    account = Account(input_private_key)
    inputs, change_outputs = create_normal_inputs(account.address(), util.TX_FEE, rpc_port)
    if inputs is None or change_outputs is None:
        Logger.error("Create normal inputs failed")
        return None

    # create outputs
    outputs = list()
    outputs.extend(change_outputs)

    # create program
    programs = list()
    redeem_script = bytes.fromhex(account.redeem_script())
    program = Program(code=redeem_script, params=None)
    programs.append(program)

    # create attributes
    attributes = list()
    attribute = Attribute(
        usage=Attribute.NONCE,
        data=bytes("attributes".encode())
    )
    attributes.append(attribute)

    # update_payload.gen_signature()

    tx = Transaction()
    tx.version = Transaction.TX_VERSION_09
    tx.tx_type = Transaction.UPDATE_CR
    tx.payload_version = 0
    tx.payload = update_payload
    tx.attributes = attributes
    tx.inputs = inputs
    tx.outputs = outputs
    tx.lock_time = 0
    tx.programs = programs

    return tx
 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
Beispiel #19
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
    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 _get_account(self, index):
        encrypt_private_key = self._accounts_data_list[index][
            "PrivateKeyEncrypted"]
        if encrypt_private_key is None:
            Logger.error("encrypt private key is None")
            return None

        encrypt_private_key_bytes = bytes.fromhex(encrypt_private_key)
        if len(encrypt_private_key_bytes) != 96:
            Logger.error("encrypt private key length is not 96")
            return None

        private_key = keytool.aes_decrypt(encrypt_private_key_bytes,
                                          self._master_key, self._iv)[64:96]
        account = Account(private_key.hex())
        return account
    def _read_key_stores(self, category: str, num: int):
        dest_path = os.path.join(self.stables_path, category + ".json")
        if not os.path.exists(dest_path):
            Logger.error(
                "{} read key stores failed, dest path {} is not found, exit..."
                .format(self.tag, dest_path))
            time.sleep(1)
            exit(-1)

        content_dict = util.read_config_file(dest_path)

        for i in range(num):
            private_key_str = content_dict[category + "_" +
                                           str(i)]["private_key"]
            a = Account(private_key_str)
            self.category_dict[category].append(a)
        Logger.debug("{} load {} keystore on success !".format(
            self.tag, category))
def create_cross_chain_transaction_by_utxo(input_private_key: str, lock_address: str, cross_chain_address: str, amount: int,
                                   recharge: bool, utxos: list):
    if lock_address is None or lock_address is "":
        Logger.error("Invalid lock address")
        return None

    if cross_chain_address is None or cross_chain_address is "":
        Logger.error("Invalid cross chain address")
        return None

    account = Account(input_private_key)
    # create outputs:
    outputs, total_amount = create_normal_outputs(
        output_addresses=[lock_address],
        amount=amount,
        fee=util.TX_FEE,
        output_lock=0
    )

    # create inputs:
    inputs, change_outputs = create_normal_inputs_by_utxo(
        account.address(), total_amount, utxos)
    if inputs is None or change_outputs is None:
        Logger.error("Create normal inputs failed")
        return None
    outputs.extend(change_outputs)

    # create program
    programs = list()
    redeem_script = bytes.fromhex(account.redeem_script())
    program = Program(code=redeem_script, params=None)
    programs.append(program)

    # create attributes
    attributes = list()
    attribute = Attribute(
        usage=Attribute.NONCE,
        data=bytes("attributes".encode())
    )
    attributes.append(attribute)

    cross_chain_asset = TransferCrossChainAsset()
    cross_chain_asset.cross_chain_addresses = [cross_chain_address]
    cross_chain_asset.output_indexes = [0]
    cross_chain_asset.cross_chain_amounts = [amount - 10000]

    tx = Transaction()
    if recharge:
        tx.version = Transaction.TX_VERSION_09
    else:
        tx.version = Transaction.TX_VERSION_DEFAULT

    # Logger.debug("transaction version {}".format(tx.version))
    tx.tx_type = Transaction.TRANSFER_CROSS_CHAIN_ASSET
    tx.payload = cross_chain_asset
    tx.attributes = attributes
    tx.inputs = inputs
    tx.outputs = outputs
    tx.lock_time = 0
    tx.programs = programs

    return tx
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):
Beispiel #25
0
class Proposal(object):
    def __init__(self, input_private_key: str, node: ElaNode, nick_name: str,
                 url: str, location: int, net_address: str):

        self.input_private_key = input_private_key
        self.input = Account(input_private_key)
        self.node = node
        self.utxo_value = 0
        self.fee = 10000
        self.state = ""
        self.deposit_amount = 5000 * util.TO_SELA
        self.info = self._producer_info(self.node.owner_account,
                                        self.node.node_account, nick_name, url,
                                        location, net_address)

    @staticmethod
    def _producer_info(owner_account: Account, node_account: Account,
                       nick_name: str, url: str, location: int,
                       net_address: str):
        info = ProducerInfo(owner_account=owner_account,
                            node_account=node_account,
                            nickname=nick_name,
                            url=url,
                            location=location,
                            net_address=net_address)
        return info

    def producer_info(self):
        return self.info

    def input_account(self):
        return self.input

    def owner_account(self):
        return self.node.owner_account

    def node_account(self):
        return self.node.node_account

    def register(self, rpc_port: int):
        tx = txbuild.create_register_transaction(
            input_private_key=self.input_private_key,
            amount=self.deposit_amount,
            payload=self.info,
            rpc_port=rpc_port)

        if tx is None:
            return None

        tx = txbuild.single_sign_transaction(self.input_private_key, tx)

        return tx

    def update(self, producer_info: ProducerInfo, rpc_port: int):
        tx = txbuild.create_update_transaction(
            input_private_key=self.input_private_key,
            payload=producer_info,
            rpc_port=rpc_port)

        if tx is None:
            return None
        producer_info.gen_signature()
        tx = txbuild.single_sign_transaction(self.input_private_key, tx)

        return tx

    def cancel(self, rpc_port: int):
        tx = txbuild.create_cancel_transaction(
            input_private_key=self.input_private_key,
            payload=self.producer_info(),
            rpc_port=rpc_port)

        if tx is None:
            return None

        tx = txbuild.single_sign_transaction(self.input_private_key, tx)

        return tx

    def redeem(self, amount: int, rpc_port: int):

        tx = txbuild.create_redeem_transaction(
            payload=self.producer_info(),
            output_address=self.input.address(),
            amount=amount,
            rpc_port=rpc_port)

        if tx is None:
            return None

        tx = txbuild.single_sign_transaction(
            self.producer_info().owner_account.private_key(), tx)

        return tx

    def active(self):

        # note activate producer transaction needn't to sign the whole transaction
        tx = txbuild.create_active_transaction(
            self.node_account().private_key(),
            self.node_account().public_key())

        if tx is None:
            return None

        return tx

    def __repr__(self):
        return self.producer_info().__repr__()
Beispiel #26
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" \
                   + "}"
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" \
               + "}"
    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))
 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())
Beispiel #30
0
 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())