Beispiel #1
0
 async def _get_logs(self, data, shard, decoder: Callable[[str], bytes]):
     start_block = data.get("fromBlock", "latest")
     end_block = data.get("toBlock", "latest")
     # TODO: not supported yet for "earliest" or "pending" block
     if (isinstance(start_block, str)
             and start_block != "latest") or (isinstance(end_block, str)
                                              and end_block != "latest"):
         return None
     # parse addresses / topics
     addresses, topics = [], []
     if "address" in data:
         if isinstance(data["address"], str):
             addresses = [Address.deserialize(decoder(data["address"]))]
         elif isinstance(data["address"], list):
             addresses = [
                 Address.deserialize(decoder(a)) for a in data["address"]
             ]
     if shard is not None:
         addresses = [Address(a.recipient, shard) for a in addresses]
     if "topics" in data:
         for topic_item in data["topics"]:
             if isinstance(topic_item, str):
                 topics.append([data_decoder(topic_item)])
             elif isinstance(topic_item, list):
                 topics.append([data_decoder(tp) for tp in topic_item])
     branch = Branch.create(self.master.get_shard_size(), shard)
     logs = await self.master.get_logs(addresses, topics, start_block,
                                       end_block, branch)
     if logs is None:
         return None
     return loglist_encoder(logs)
Beispiel #2
0
 async def eth_getTransactionCount(self, address, shard=None):
     address = Address.deserialize(address)
     if shard is not None:
         address = Address(address.recipient, shard)
     account_branch_data = await self.master.get_primary_account_data(
         address)
     return account_branch_data.transaction_count
Beispiel #3
0
 async def eth_getBalance(self, address, shard=None):
     address = Address.deserialize(address)
     if shard is not None:
         address = Address(address.recipient, shard)
     account_branch_data = await self.master.get_primary_account_data(address)
     balance = account_branch_data.balance
     return balance
Beispiel #4
0
    async def donate(self, from_address, to_address, value=hex(10 ** 18)):
        """Faucet function to send value (default 1 token) from from_address to to_address.
        from_address must be one of the addresses in genesis_data/alloc.json.
        Only allow one pending tx at a time.
        Return tx id if success else None
        """
        if value > 100 * (10 ** 18):
            return None

        key = self.master.env.quark_chain_config.alloc_accounts.get(
            from_address.hex(), None
        )
        if not key:
            return None

        from_address = Address.deserialize(from_address)
        to_address = Address.deserialize(to_address)

        # Do nothing if there is already a pending tx
        result = await self.master.get_transactions_by_address(
            from_address, bytes(1), 1
        )
        if result:
            tx_list, next_token = result
            if tx_list:
                return None

        account_branch_data = await self.master.get_primary_account_data(from_address)
        nonce = account_branch_data.transaction_count
        network_id = self.master.env.quark_chain_config.NETWORK_ID
        evm_tx = EvmTransaction(
            nonce,
            10 ** 9,
            30000,
            to_address.recipient,
            value,
            b"",
            from_full_shard_id=from_address.full_shard_id,
            to_full_shard_id=to_address.full_shard_id,
            network_id=network_id,
        )
        evm_tx.sign(key)
        tx = Transaction(code=Code.create_evm_code(evm_tx))
        success = await self.master.add_transaction(tx)
        if not success:
            return None
        return id_encoder(tx.get_hash(), from_address.full_shard_id)
Beispiel #5
0
    async def getAccountData(self,
                             address,
                             block_height=None,
                             include_shards=False):
        # do not allow specify height if client wants info on all shards
        if include_shards and block_height is not None:
            return None

        primary = None
        address = Address.deserialize(address)
        if not include_shards:
            account_branch_data = await self.master.get_primary_account_data(
                address, block_height)
            branch = account_branch_data.branch
            count = account_branch_data.transaction_count

            balances = account_branch_data.token_balances
            primary = {
                "fullShardId": quantity_encoder(branch.get_full_shard_id()),
                "shardId": quantity_encoder(branch.get_shard_id()),
                "chainId": quantity_encoder(branch.get_chain_id()),
                "balances": balances_encoder(balances),
                "transactionCount": quantity_encoder(count),
                "isContract": account_branch_data.is_contract,
            }
            return {"primary": primary}

        branch_to_account_branch_data = await self.master.get_account_data(
            address)

        shards = []
        for branch, account_branch_data in branch_to_account_branch_data.items(
        ):
            balances = account_branch_data.token_balances
            data = {
                "fullShardId":
                quantity_encoder(branch.get_full_shard_id()),
                "shardId":
                quantity_encoder(branch.get_shard_id()),
                "chainId":
                quantity_encoder(branch.get_chain_id()),
                "balances":
                balances_encoder(balances),
                "transactionCount":
                quantity_encoder(account_branch_data.transaction_count),
                "isContract":
                account_branch_data.is_contract,
            }
            shards.append(data)

            if branch.get_full_shard_id(
            ) == self.master.env.quark_chain_config.get_full_shard_id_by_full_shard_key(
                    address.full_shard_key):
                primary = data

        return {"primary": primary, "shards": shards}
Beispiel #6
0
 async def getBalance(self, address, block_height=None):
     account_branch_data = await self.master.get_primary_account_data(
         Address.deserialize(address), block_height)
     branch = account_branch_data.branch
     balance = account_branch_data.balance
     return {
         "branch": quantity_encoder(branch.value),
         "shard": quantity_encoder(branch.get_shard_id()),
         "balance": quantity_encoder(balance),
     }
Beispiel #7
0
 async def getBalances(self, address, block_height=None):
     account_branch_data = await self.master.get_primary_account_data(
         Address.deserialize(address), block_height)
     branch = account_branch_data.branch
     balances = account_branch_data.token_balances
     return {
         "branch": quantity_encoder(branch.value),
         "fullShardId": quantity_encoder(branch.get_full_shard_id()),
         "shardId": quantity_encoder(branch.get_shard_id()),
         "chainId": quantity_encoder(branch.get_chain_id()),
         "balances": balances_encoder(balances),
     }
Beispiel #8
0
 async def getNextBlockToMine(self,
                              coinbase_address,
                              shard_mask_value,
                              prefer_root=False):
     address = Address.deserialize(coinbase_address)
     is_root_block, block = await self.master.get_next_block_to_mine(
         address, shard_mask_value, prefer_root=prefer_root)
     if not block:
         return None
     return {
         "isRootBlock": is_root_block,
         "blockData": data_encoder(block.serialize()),
     }
Beispiel #9
0
    async def getAccountData(self,
                             address,
                             block_height=None,
                             include_shards=False):
        # do not allow specify height if client wants info on all shards
        if include_shards and block_height is not None:
            return None

        address = Address.deserialize(address)
        if not include_shards:
            account_branch_data = await self.master.get_primary_account_data(
                address, block_height)
            branch = account_branch_data.branch
            balance = account_branch_data.balance
            count = account_branch_data.transaction_count
            primary = {
                "branch": quantity_encoder(branch.value),
                "shard": quantity_encoder(branch.get_shard_id()),
                "balance": quantity_encoder(balance),
                "transactionCount": quantity_encoder(count),
                "isContract": account_branch_data.is_contract,
            }
            return {"primary": primary}

        branch_to_account_branch_data = await self.master.get_account_data(
            address)
        shard_size = self.master.get_shard_size()

        shards = []
        for shard in range(shard_size):
            branch = Branch.create(shard_size, shard)
            account_branch_data = branch_to_account_branch_data[branch]
            data = {
                "branch":
                quantity_encoder(account_branch_data.branch.value),
                "shard":
                quantity_encoder(account_branch_data.branch.get_shard_id()),
                "balance":
                quantity_encoder(account_branch_data.balance),
                "transactionCount":
                quantity_encoder(account_branch_data.transaction_count),
                "isContract":
                account_branch_data.is_contract,
            }
            shards.append(data)

            if shard == address.get_shard_id(shard_size):
                primary = data

        return {"primary": primary, "shards": shards}
Beispiel #10
0
 async def eth_getCode(self, address, shard=None):
     addr = Address.deserialize(address)
     if shard is not None:
         addr = Address(addr.recipient, shard)
     res = await self.master.get_code(addr, None)
     return data_encoder(res) if res is not None else None
Beispiel #11
0
 async def getCode(self, address, block_height=None):
     res = await self.master.get_code(Address.deserialize(address),
                                      block_height)
     return data_encoder(res) if res is not None else None
Beispiel #12
0
 async def getStorageAt(self, address, key, block_height=None):
     res = await self.master.get_storage_at(Address.deserialize(address),
                                            key, block_height)
     return data_encoder(res) if res is not None else None
Beispiel #13
0
 async def getTransactionCount(self, address, block_height=None):
     account_branch_data = await self.master.get_primary_account_data(
         Address.deserialize(address), block_height)
     return account_branch_data.transaction_count