EOSIO / eos

An open source smart contract platform
https://developers.eos.io/manuals/eos
MIT License
11.28k stars 3.6k forks source link

chain_api_plugin get_table_rows table_key is not used #3695

Closed heifner closed 6 years ago

heifner commented 6 years ago

Currently, the table_key passed to get_table_rows of chain_api_plugin is not used. As such, it is not possible to specify the table key used for retrieval and only the primary key can be used to get table rows.

taokayan commented 6 years ago

Hi, I've created a pull request https://github.com/EOSIO/eos/pull/4053 to support "get table" with any secondary index without the need of modifying abi file. Please would you review this?

FortisFortuna commented 6 years ago

This is badly needed -- I am having to do workarounds to convert strings into uint64_t's on any table that needs to be referenced by the API, which uses the get table command.

taokayan commented 6 years ago

you can put any account name(string) as "lower bound" of i64, and conversion is implicitly performed.

FortisFortuna commented 6 years ago

Javascript has a 58-bit limit on integers, so you have to do Mod 9007199254740991, which can lead to collisions (this is when using eosjs). Overall, it would be nice to be able to cleos get table with secondary keys. It works fine within the smart contract code right now, but not the API. There can also be issues with endianness.

taokayan commented 6 years ago

brief description: This feature allows the user to query any table by primary or secondary indexes of different types.

Index position logic: first index will always be primary index(type i64), then the 2nd to the N indexes correspond to the order of indexed_by in the mult_index typedef. For example:

eosio::multi_index< N(namebids), name_bid,
                               indexed_by<N(highbid), const_mem_fun<name_bid, uint64_t, &name_bid::by_high_bid>  >
                               >  name_bid_table;

1st index: index of primary_key 2nd index: index of by_high_bid

get table command new parameters:

 --index TEXT                Index number, 1 - primary (first), 2 - secondary index (in order defined by multi_index), 3 - third index, etc.
                Number or name of index can be specified, e.g. 'secondary' or '2'.
  --key-type TEXT             The key type of --index, primary only supports (i64), all others support (i64, i128, i256, float64, float128).
                Special type 'name' indicates an account name.

Command example:

Get all the bids sorted by highbid:

./cleos get table eosio eosio namebids --key-type i64 --index 2
{
  "rows": [{
      "newname": "zoo",
      "high_bidder": "a123",
      "high_bid": 9990000,
      "last_bid_time": "1528797387500000"
    },{
      "newname": "ddd",
      "high_bidder": "a123",
      "high_bid": 120000,
      "last_bid_time": "1528797387500000"
    },{
      "newname": "abc",
      "high_bidder": "a123",
      "high_bid": 110000,
      "last_bid_time": "1528797387500000"
    },{
      "newname": "com",
      "high_bidder": "a123",
      "high_bid": 100000,
      "last_bid_time": "1528797387000000"
    }
  ],
  "more": false
}

Get all the producers which have votes equal to zero:

./cleos get table eosio eosio producers --key-type float64 --index 2 -L "0" -U "0.00001"
{
  "rows": [{
      "owner": "a123",
      "total_votes": "0.00000000000000000",
      "producer_key": "EOS8kE63z4NcZatvVWY4jxYdtLg6UEA123raMGwS6QDKwpQ69eGcP",
      "is_active": 1,
      "url": "",
      "unpaid_blocks": 0,
      "last_claim_time": 0,
      "location": 0
    }
  ],
  "more": false
}
heifner commented 6 years ago

Resolved by #4053