Skip to content

Latest commit

 

History

History
159 lines (131 loc) · 5.5 KB

tip-295.md

File metadata and controls

159 lines (131 loc) · 5.5 KB
tip: 295
title: Optimize account assets	
author: forfreeday@163.com
discussions to: https://github.com/tronprotocol/TIPs/issues/295
status: Final 
type: Standards Track
category: Core
created: 2021-07-15

Simple Summary

Separate storage of account and asset data to improve the speed of serialization deserialization of accounts and assets.

Abstract

In the current account model data structure, account balance data and asset data are stored in AccountStore. When querying an account, asset-related data will also be queried and serialized, which will lead to slow serialization performance and affect query efficiency. In this regard, the account and asset data are stored separately to reduce the data volume and product and improve the speed of deserialization.

Motivation

In the current project, there is very little coupling between the operations of different types of assets, and the account balance data and asset data are different types of data with little correlation. The number of assets data used is relatively small in the current business, but its data does affect the deserialization speed of the accounts. Therefore storing the asset data separately and populating it when it is needed can improve the deserialization speed of the account. Separate storage can also be logically decoupled. It can also improve the performance of TVM when using account related data.

Specification

  1. Create AccountAssetStore 2.Populate data when querying assets 3.Splitting when saving an account

1.Create AccountAssetStore Create a database to store split assets and save asset data.

Data structure of the AccountAsset

/* AccountAsset */
message AccountAsset {

  /* frozen balance */
  message Frozen {
    int64 frozen_balance = 1; // the frozen trx balance
    int64 expire_time = 2; // the expire time
  }

  // the create address
  bytes address = 1;

  // the other asset owned by this account
  map<string, int64> asset = 2;

  // the other asset owned by this account,key is assetId
  map<string, int64> assetV2 = 3;

  bytes asset_issued_name = 4;
  bytes asset_issued_ID = 5;

  map<string, int64> latest_asset_operation_time = 6;
  map<string, int64> latest_asset_operation_timeV2 = 7;

  map<string, int64> free_asset_net_usage = 8;
  map<string, int64> free_asset_net_usageV2 = 9;

  // frozen asset(for asset issuer)
  repeated Frozen frozen_supply = 10;
}

2.Populate data when querying assets When the data is split, only the account data is returned when the account is queried to reduce the size. If the assets in the account are used, the asset data is populated by querying the assets, and this operation is done automatically.

3.When saving the account, splitting is performed. When saving an account, the AccountStore.put method is used as a proxy for the AccountAssetStore.put method to store the account separately.

Implementation

When operating the account for the first time, the account is split and then stored. For operations that do not require asset data, the account only needs to deserialize the account data.

  1. Create AccountAssetStore to store asset data
  2. proxy the method of manipulating assets in AccountCapsule, and populate the asset data when manipulating assets
  3. Separate when storing AccountStore

1.Create AccountAssetStore to store asset data

2.Proxy methods for manipulating assets in AccountCapsule, and populate asset data when manipulating assets The methods that require asset manipulation are in AccountCapsule, including.

3.When saving the account, splitting is performed.

clearAssetV2()
clearLatestAssetOperationTimeV2()
clearFreeAssetNetUsageV2()
assetBalanceEnoughV2()
reduceAssetAmount()
reduceAssetAmountV2()
addAssetAmount()
addAssetAmountV2()
addAsset()
addAssetV2()
addAssetMapV2()
getAssetMap()
getAssetMapV2()
addAllLatestAssetOperationTimeV2()
getLatestAssetOperationTimeMap()
getLatestAssetOperationTimeMapV2()
getLatestAssetOperationTime()
getLatestAssetOperationTimeV2()
putLatestAssetOperationTimeMap()
putLatestAssetOperationTimeMapV2()
getFrozenSupplyCount()
getFrozenSupplyList()
getAssetIssuedName()
setAssetIssuedName()
getAssetIssuedID()
setAssetIssuedID()
addAllFreeAssetNetUsageV2()
getFreeAssetNetUsageV2()
getAllFreeAssetNetUsage()
getAllFreeAssetNetUsageV2()
putFreeAssetNetUsage()
putFreeAssetNetUsageV2()

All of these methods perform asset synchronization operations when used Examples

  public Map<String, Long> getAssetMap() {
    //fill data
    importAsset();
    Map<String, Long> assetMap = this.account.getAssetMap();
    if (assetMap.isEmpty()) {
      assetMap = Maps.newHashMap();
    }

    return assetMap;
  }

3.Separation when storing AccountStore When the account is stored, the data is stored separately in the AccountStore and AccountAssetStore

  public void put(byte[] key, AccountCapsule item) {
  . ...
    if (AssetUtil.isAllowAssetOptimization()) {
      Account account = item.getInstance();
      //separate asset data
      AccountAsset accountAsset = AssetUtil.getAsset(account);
      if (null != accountAsset) {
        accountAssetStore.put(key, new AccountAssetCapsule(
                accountAsset));
        account = AssetUtil.clearAsset(account);
        item.setIsAssetImport(false);
        item.setInstance(account);
      }
    }
    super.put(key, item);
    accountStateCallBackUtils.accountCallBack(key, item);
  }

Rationale

TRC10 assets are a separate TOKEN type and are fully capable of being stored separately. In java-tron the balance TRC10 TRC20 is not affected in any way between separate storage