Exemplo n.º 1
0
    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
Exemplo n.º 2
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
    def register_producers_candidates(self):

        global result
        result = False
        for i in range(
                self.params.ela_params.crc_number + 1,
                self.params.ela_params.number - round(self.params.ela_params.later_start_number / 2) + 1
        ):
            ela_node = self.node_manager.ela_nodes[i]
            public_key = ela_node.node_account.public_key()
            ret = self.register_producer(ela_node)
            if not ret:
                return False
            rpc.discrete_mining(7)

            status = rpc.producer_status(public_key)
            Logger.debug("After mining 7 blocks, register status: {}".format(status))
            result = status == "Active"
            if not result:
                Logger.error("{} register producer {} failed".format(self.tag, ela_node.name))
                break

            Logger.info("{} register node-{} to be a producer on success!\n".format(self.tag, i))

        return result
    def _check_password(self):
        ret = keytool.sha256_hash(str.encode(self._password),
                                  3).hex() == self._get_password_hash()
        if not ret:
            Logger.error("Invalid password!")

        return ret
Exemplo n.º 5
0
    def get_dpos_real_income(self, height: int):
        response = rpc.get_block_by_height(height)
        if response is False or not isinstance(response, dict):
            Logger.error("{} rpc response invalid".format(self.tag))
            return None

        # Logger.debug("{} response: {}".format(self.tag, response))
        vout_list = response["tx"][0]["vout"]
        Logger.debug("{} vout list length: {}".format(self.tag,
                                                      len(vout_list)))
        sum = 0.0
        income_dict = dict()
        for vout in vout_list:
            address = vout["address"]
            if address == self.foundation_account.address(
            ) or address == self.node_manager.main_miner_address:
                continue

            value = float(vout["value"])
            if isinstance(address, str) and address.startswith("8"):
                income_dict["CRC-I"] = value * constant.TO_SELA
            else:
                income_dict[self.node_manager.address_name_dict[
                    address]] = value * constant.TO_SELA
            sum += value

        Logger.debug("{} income dict: {}".format(self.tag,
                                                 sorted(income_dict.items())))
        Logger.debug("{} dpos votes: {}".format(self.tag,
                                                self.dpos_votes_dict))
        return income_dict
 def add_sub_account(self, sub_account: Account):
     if not self._valid:
         Logger.error("Invalid keystore!")
         return
     self._sub_accounts_list.append(sub_account)
     sub_account_data = self._create_account_data(sub_account,
                                                  self.SUB_ACCOUNT)
     self._accounts_data_list.append(sub_account_data)
    def has_dpos_reward(self, height: int):
        response = rpc.get_block_by_height(height)
        if response is False:
            Logger.error("{} rpc response invalid".format(self.tag))
            return False

        # Logger.debug("{} response: {}".format(self.tag, response))
        return len(response["tx"][0]["vout"]) > 2
Exemplo n.º 8
0
def arbiter_public_keys(key_stores):
    public_keys = []
    if len(key_stores) != 5:
        Logger.error("[common] Invalid argument, the length of the argument must be equal 5")
        exit(0)
    for key_store in key_stores:
        public_keys.append(key_store.public_key.hex())
    return public_keys
    def get_dpos_theory_income(self, block_num: int, tx_fee: int,
                               dpos_votes: dict):
        Logger.debug("{} block num: {}".format(self.tag, block_num))
        Logger.debug("{} tx fee: {}".format(self.tag, tx_fee))
        dpos_origin_income = math.ceil(self.get_reward_per_block() * 35 /
                                       100) * block_num + (tx_fee * 35 / 100)
        Logger.debug("{} dpos origin income: {}".format(
            self.tag, dpos_origin_income))
        total_block_confirm_reward = math.floor(dpos_origin_income * 25 / 100)
        total_top_producers_reward = math.floor(dpos_origin_income * 75 / 100)

        Logger.debug("{} income1: {}".format(self.tag,
                                             total_block_confirm_reward))
        Logger.debug("{} income2: {}".format(self.tag,
                                             total_top_producers_reward))

        current_arbiters = self.get_arbiter_names("arbiters")
        if not current_arbiters:
            Logger.error("{} get current arbiters info error".format(self.tag))
            return None

        current_candidates = self.get_arbiter_names("candidates")
        if not current_candidates:
            Logger.error("{} get current candidates info error".format(
                self.tag))
            return None

        individual_first_reward = math.floor(total_block_confirm_reward /
                                             len(current_arbiters))
        total_votes = dpos_votes["total"]
        Logger.debug("dpos total votes: {}".format(total_votes))
        individual_second_reward = math.floor(total_top_producers_reward /
                                              total_votes)
        Logger.debug("{} income1 each: {}".format(self.tag,
                                                  individual_first_reward))
        Logger.debug("{} income2 each: {}".format(self.tag,
                                                  individual_second_reward))

        theory_incomes = dict()

        # calculate current arbiter rewards
        theory_incomes["CRC-I"] = individual_first_reward * 4
        for node_name in current_arbiters:
            if node_name.startswith("CRC"):
                continue
            theory_incomes[node_name] = individual_first_reward + dpos_votes[
                node_name] * individual_second_reward

        # calculate current candidates rewards
        for node_name in current_candidates:
            if node_name.startswith("CRC"):
                continue
            theory_incomes[
                node_name] = dpos_votes[node_name] * individual_second_reward

        Logger.debug("{} theory income: {}".format(
            self.tag, sorted(theory_incomes.items())))
        return theory_incomes
Exemplo n.º 10
0
 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)
Exemplo n.º 11
0
    def get_master_key(self):
        password_twice_hash = keytool.sha256_hash(str.encode(self.password), 2)
        encrypt_master_key = self.get_encrypt_master_key()
        if encrypt_master_key is None:
            Logger.error("encrypt master key is None")
            return None

        master_key = keytool.aes_decrypt(bytes.fromhex(encrypt_master_key),
                                         password_twice_hash, self.iv)

        return master_key
Exemplo n.º 12
0
 def stop(self):
     if not self.running:
         Logger.error("{} arbiter{} has already stopped".format(self.tag, self.index))
         return
     try:
         self.process.terminate()
         self.dev_null.close()
         self.err_output.close()
     except subprocess.SubprocessError as e:
         Logger.error("{} Unable to stop arbiter{}, error: {}".format(self.tag, self.index, e))
     self.running = False
    def serialize(self, version: int):
        if self.candidates is None or len(self.candidates) == 0:
            Logger.error("candidates list is empty!")
            return None
        r = b""
        r += struct.pack("<B", self.vote_type)
        r += serialize.write_var_uint(len(self.candidates))
        for candidate in self.candidates:
            r = serialize.write_var_bytes(r, candidate)

        return r
Exemplo n.º 14
0
    def get_encrypt_private_key(self):
        if "Account" not in self.keystore_dat.keys():
            Logger.error("keystore_dat dose not contain key Account")
            return None

        at = self.keystore_dat["Account"][0]
        if "PrivateKeyEncrypted" not in at.keys():
            Logger.error("Account dose not contain key PrivateKeyEncrypted")
            return None

        return at["PrivateKeyEncrypted"]
    def serialize(self):
        if self.contents is None or len(self.contents) == 0:
            Logger.error("contents is invalid")
            return None

        r = b""
        r += struct.pack("<B", self.version)
        r += serialize.write_var_uint(len(self.contents))
        for content in self.contents:
            r += content.serialize(self.version)

        return r
Exemplo n.º 16
0
def get_request(url):
    try:
        Logger.debug("{} get request url: {}".format(tag, url))
        response = requests.get(url)
        resp = response.json()
        if resp["Desc"] == "Success":
            return resp["Result"]
        else:
            return None
    except requests.exceptions.RequestException as e:
        Logger.error("{} get request error: {}".format(tag, e))
        return False
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 handle_tx_result(self, tx: Transaction, port=rpc.DEFAULT_PORT):
        r = tx.serialize()
        response = rpc.send_raw_transaction(r.hex(), port)
        if isinstance(response, dict):
            Logger.error("{} rpc response: {}".format(self.tag, response))
            Logger.error("rpc send raw transaction failed")
            return False

        tx_hash = util.bytes_reverse(bytes.fromhex(tx.hash())).hex()
        Logger.debug("{} tx hash : {}".format(self.tag, tx_hash))
        Logger.debug("{} response: {}".format(self.tag, response))

        return tx_hash
    def key_store_dict(self):
        if not self._valid:
            Logger.error("Invalid keystore!")
            return None
        store_dict = {
            "Version": "1.0.0",
            "PasswordHash": self._password_thrice_hash.hex(),
            "IV": self._iv.hex(),
            "MasterKey": self._master_key_encrypted.hex(),
            "Account": self._accounts_data_list
        }

        return store_dict
def create_normal_inputs(address: str, total_amount: int, rpc_port: int, utxo_index=-1):
    global total_amount_global
    global response
    total_amount_global = total_amount

    response = rpc.list_unspent_utxos(address, port=rpc_port)
    if not response or isinstance(response, dict):
        Logger.error("get utxos return error: {}".format(response))
        return None, None
    utxos = response
    if utxo_index >= 0 and len(utxos) >= utxo_index+1:
        utxo = utxos[utxo_index]
        utxos = list()
        utxos.append(utxo)

    inputs = list()
    change_outputs = list()

    program_hash = keytool.address_to_program_hash(address)

    for utxo in utxos:
        txid = util.bytes_reverse(bytes.fromhex(utxo["txid"]))
        index = utxo["vout"]
        input = Input(txid, index)
        inputs.append(input)

        amount = int(Decimal(utxo["amount"]) * util.TO_SELA)

        if amount < total_amount_global:
            # total_amount -= amount
            total_amount_global -= amount
        elif amount == total_amount_global:
            total_amount_global = 0
            break
        elif amount > total_amount_global:
            change = Output(
                value=amount - total_amount_global,
                output_lock=0,
                program_hash=program_hash,
                output_type=Output.OT_NONE,
                output_payload=OutputPayload()
            )
            change_outputs.append(change)
            total_amount_global = 0
            break

    if total_amount_global > 0:
        Logger.error("Available token is not enough!")
        return None, None

    return inputs, change_outputs
Exemplo n.º 21
0
def create_normal_inputs(address: str, total_amount: int, port=rpc.DEFAULT_PORT):
    global total_amount_global
    global response
    total_amount_global = total_amount
    total_amount_format = str(Decimal(str(total_amount_global)) / Decimal(constant.TO_SELA))

    if port != rpc.DEFAULT_PORT:
        response = rpc.list_unspent_utxos(address, port=port)
    else:
        response = rpc.get_utxos_by_amount(address, total_amount_format, port)
    if not response or isinstance(response, dict):
        Logger.debug("get utxos return error: {}".format(response))
        return None, None
    utxos = response

    Logger.debug("utxos: {}".format(utxos))
    inputs = list()
    change_outputs = list()

    program_hash = keytool.address_to_program_hash(address)

    for utxo in utxos:
        txid = util.bytes_reverse(bytes.fromhex(utxo["txid"]))
        index = utxo["vout"]
        input = Input(txid, index)
        inputs.append(input)

        amount = int(Decimal(utxo["amount"]) * constant.TO_SELA)

        if amount < total_amount_global:
            total_amount -= amount
        elif amount == total_amount:
            total_amount_global = 0
            break
        elif amount > total_amount:
            change = Output(
                value=amount - total_amount_global,
                output_lock=0,
                program_hash=program_hash,
                output_type=Output.OT_NONE,
                output_payload=OutputPayload()
            )
            change_outputs.append(change)
            total_amount_global = 0
            break

    if total_amount_global > 0:
        Logger.error("Available token is not enough!")
        return None, None

    return inputs, change_outputs
Exemplo n.º 22
0
    def start(self):
        Logger.info("remove old geth.")
        # rm old geth
        gethfile = os.path.join(self.config["gopath"], "bin/geth")
        bootnodefile = os.path.join(self.config["gopath"], "bin/bootnode")
        oraclefold = os.path.join(
            self.config["gopath"],
            "src/github.com/elastos/Elastos.ELA.SideChain.ETH/oracle")
        if os.path.exists(gethfile):
            os.remove(gethfile)
        Logger.info("start complie geth.")
        subprocess.Popen("sh ./replace_compile.sh",
                         stdout=self.dev_null,
                         stderr=self.err_output,
                         shell=True,
                         cwd=self.cwd_dir)
        timecount = 60
        while True:
            timecount -= 1
            if timecount <= 0:
                break
            if os.path.exists(gethfile):
                shutil.copy(gethfile, os.path.join(self.cwd_dir, "ethnode1"))
                shutil.copy(gethfile, os.path.join(self.cwd_dir, "ethnode2"))
                shutil.copy(gethfile, os.path.join(self.cwd_dir, "ethnode3"))
                shutil.copy(bootnodefile, os.path.join(self.cwd_dir, "v4"))
                shutil.copy(bootnodefile, os.path.join(self.cwd_dir, "v5"))
                shutil.copytree(oraclefold,
                                os.path.join(self.cwd_dir, "oracle"))
                break
            time.sleep(1)

        if timecount == 0:
            Logger.error("compile geth fail.")
            subprocess.Popen("sh ./killall.sh",
                             stdout=self.dev_null,
                             stderr=self.err_output,
                             shell=True,
                             cwd=self.cwd_dir)
            exit(1)
        Logger.info("start  geth.")
        self.process = subprocess.Popen("sh ./gethstart.sh",
                                        stdout=self.dev_null,
                                        stderr=self.err_output,
                                        shell=True,
                                        cwd=self.cwd_dir)
        time.sleep(0.5)
        self.running = True
        Logger.debug("eth nodes started on success.")
        return True
Exemplo n.º 23
0
    def serialize(self, r: bytes, version: int):
        if len(self.cross_chain_addresses) != len(self.output_indexes) or \
                len(self.cross_chain_addresses) != len(self.cross_chain_addresses):
            Logger.error("Invalid cross chain asset")
            return None

        r += serialize.write_var_uint(len(self.cross_chain_addresses))

        for i in range(len(self.cross_chain_addresses)):
            r = serialize.write_var_bytes(r, bytes(self.cross_chain_addresses[i].encode()))
            r += serialize.write_var_uint(self.output_indexes[i])
            r += struct.pack("<q", self.cross_chain_amounts[i])

        return r
Exemplo n.º 24
0
def post_request(url, method, params):
    try:
        Logger.debug("{} method: {}".format(tag, method))
        Logger.debug("{} params: {}".format(tag, params))
        response = requests.post(url, json={"method": method, "params": params},
                             headers={"content-type": "application/json"})
        resp = response.json()
        if resp["error"] == None:
            return resp["result"]
        else:
            return resp["error"]
    except requests.exceptions.RequestException as e:
        Logger.error("{} post request error: {}".format(tag, e))
        return False
Exemplo n.º 25
0
    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
Exemplo n.º 26
0
 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 save_to_file(self, dest_dir_path: str):
        if not self._valid:
            Logger.error("Invalid keystore!")
            return False
        if dest_dir_path is "":
            Logger.debug("Invalid parameter!")
            return False

        if not os.path.exists(dest_dir_path):
            os.makedirs(dest_dir_path)

        file_path = os.path.join(dest_dir_path, "keystore.dat")
        util.write_config_file(self.key_store_dict(), file_path)

        return True
Exemplo n.º 28
0
    def get_private_key(self):
        encrypt_private_key = self.get_encrypt_private_key()
        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.mater_key, self.iv)

        return private_key[64:96]
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
Exemplo n.º 30
0
def create_register_transaction(keystore: KeyStore, output_addresses: list, amount: int,
                                payload: ProducerInfo, fee=10000, output_lock=0):
    # 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=fee,
        output_lock=output_lock
    )

    # create inputs
    inputs, change_outputs = create_normal_inputs(keystore.address(), total_amount)
    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 = keystore.sign_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.REGISTER_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