ord icon indicating copy to clipboard operation
ord copied to clipboard

feat: add query endpoints for balances of specific runes

Open nghuyenthevinh2000 opened this issue 10 months ago • 6 comments

fixes: #3667

The logic will fetch balances of specific rune in each outpoint. Not loading the whole balances map.

Logic

  1. add endpoint "/rune/:rune/balances" which allows specifying rune to fetch balances
  2. add rune_specific_balances() to Server
  3. add get_rune_specific_balances() to Index: use OUTPOINT_TO_RUNE_BALANCES, and then filter specific rune balances

Testing

  1. get_rune_specific_balances(): querying balances from specific rune 0, 1, 2

@raphjaph hi, this is my first PR, I hope to explore more into the codebase. Any constructive feedbacks are welcome!

nghuyenthevinh2000 avatar Apr 24 '24 12:04 nghuyenthevinh2000

@casey Hi, can you check if this one satisfies your requirement enough?

https://github.com/ordinals/ord/pull/3069#issuecomment-1925038948

nghuyenthevinh2000 avatar Apr 24 '24 14:04 nghuyenthevinh2000

This PR has a good form, you have a good description and also added a test. Unfortunately we need another table to make this an efficient call. You can try your hand at this, or, if you want, I could show how to add another table into the database in the next Ordinals Coding Club. Let me know what you prefer :)

I can try adding it to table, thanks for your feedback

nghuyenthevinh2000 avatar May 06 '24 09:05 nghuyenthevinh2000

@raphjaph I have added a new table: RUNE_ID_TO_OUTPOINTS_BALANCE which tracks rune id to bytes array of (outpoints, balance)

Logic

  1. Add table RUNE_ID_TO_OUTPOINTS_BALANCE update in index/rune_updater.rs
  2. Add encode, decode scheme for bytes array of (outpoints, balance)
  3. Update get_rune_specific_balances(): get exactly a map of (outpoints, balance) from rune id

Test

  1. test_encode_decode_rune_to_outpoints_balance()
  2. past test get_rune_specific_balances() works as intended

nghuyenthevinh2000 avatar May 07 '24 12:05 nghuyenthevinh2000

Runes can be in multiple outpoints so this the table should be a multi map. Also we already have the table OUTPOINT_TO_RUNE_BALANCES so we don't have to store the balance inside the new table.

The query needs a mapping from a rune id to a byte array of multiple n outpoints.

OUTPOINT_TO_RUNE_BALANCES maps an outpoint to a byte array of multiple m (rune, balances) so I would still have to go through the whole byte array to extract the balance of that specific rune, thus O(n*m)

So, I think why not also include balance of such specific rune in each out point (out point, balance of specific rune) as well, one less iteration. Thus, RUNE_ID_TO_OUTPOINTS_BALANCE, the cost of querying is greatly reduced to O(n)

nghuyenthevinh2000 avatar May 08 '24 14:05 nghuyenthevinh2000

@raphjaph can you check this one again,cargo test are passing on my local mac

Screenshot 2024-05-10 at 13 15 41

nghuyenthevinh2000 avatar May 10 '24 05:05 nghuyenthevinh2000

@nghuyenthevinh2000 Have you run an index with this and compared it to the size without this table? This might be a big table and take longer to index so I'm inclined to put it behind a flag like --index-rune-utxos or --index-rune-balances.

Also what is the reason to make a the table RUNE_ID_TO_OUTPOINTS_BALANCE instead of just doing RUNE_ID_TO_OUTPOINTS and then get the balance from the OUTPOINT_TO_RUNE_BALANCES table? I think this could save you some decoding logic and database size.

raphjaph avatar Jun 28 '24 16:06 raphjaph