Skip to content

Commit 6885ee5

Browse files
authored
Merge pull request #1105 from oasisprotocol/ptrus/feature/na-holders
api/runtime/tokens: Omit num_holders and num_transfers if unknown
2 parents 1bb3240 + 7a1be0a commit 6885ee5

File tree

13 files changed

+44
-18
lines changed

13 files changed

+44
-18
lines changed

.changelog/1105.feature.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
api/runtime/tokens: Omit num_holders and num_transfers if unknown
2+
3+
Tokens that emit no events (like BitUSD) will omit num_holders and
4+
num_transfers instead of returning zeroes.

analyzer/queries/queries.go

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -866,28 +866,30 @@ var (
866866
// NOTE: Passing a 0 for last_mutate round causes that field to not be updated, effectively signalling
867867
// "this upsert does not create a need for a subsequent download of info from the EVM runtime".
868868
RuntimeEVMTokenDeltaUpsert = `
869-
INSERT INTO chain.evm_tokens AS old (runtime, token_address, total_supply, num_transfers, last_mutate_round)
870-
VALUES ($1, $2, $3, $4, $5)
869+
INSERT INTO chain.evm_tokens AS old (runtime, token_address, total_supply, num_transfers, likely_no_events, last_mutate_round)
870+
VALUES ($1, $2, $3, $4, $5, $6)
871871
ON CONFLICT (runtime, token_address) DO UPDATE SET
872872
total_supply = old.total_supply + $3,
873873
num_transfers = old.num_transfers + $4,
874-
last_mutate_round = GREATEST(old.last_mutate_round, $5)`
874+
likely_no_events = excluded.likely_no_events AND old.likely_no_events,
875+
last_mutate_round = GREATEST(old.last_mutate_round, $6)`
875876

876877
RuntimeFastSyncEVMTokenDeltaInsert = `
877-
INSERT INTO todo_updates.evm_tokens AS old (runtime, token_address, total_supply, num_transfers, last_mutate_round)
878-
VALUES ($1, $2, $3, $4, $5)`
878+
INSERT INTO todo_updates.evm_tokens AS old (runtime, token_address, total_supply, num_transfers, likely_no_events, last_mutate_round)
879+
VALUES ($1, $2, $3, $4, $5, $6)`
879880

880881
RuntimeEVMTokenRecompute = `
881-
INSERT INTO chain.evm_tokens AS old (runtime, token_address, total_supply, num_transfers, last_mutate_round)
882+
INSERT INTO chain.evm_tokens AS old (runtime, token_address, total_supply, num_transfers, likely_no_events, last_mutate_round)
882883
(
883-
SELECT runtime, token_address, SUM(total_supply) AS total_supply, SUM(num_transfers) AS num_transfers, MAX(last_mutate_round) AS last_mutate_round
884+
SELECT runtime, token_address, SUM(total_supply) AS total_supply, SUM(num_transfers) AS num_transfers, BOOL_AND(likely_no_events) AS likely_no_events, MAX(last_mutate_round) AS last_mutate_round
884885
FROM todo_updates.evm_tokens
885886
WHERE runtime = $1
886887
GROUP BY runtime, token_address
887888
)
888889
ON CONFLICT (runtime, token_address) DO UPDATE SET
889890
total_supply = old.total_supply + excluded.total_supply,
890891
num_transfers = old.num_transfers + excluded.num_transfers,
892+
likely_no_events = old.likely_no_events AND excluded.likely_no_events,
891893
last_mutate_round = GREATEST(old.last_mutate_round, excluded.last_mutate_round)`
892894

893895
// Upserts a new EVM token with information that was downloaded from the EVM runtime (as opposed to dead-reckoned).

analyzer/runtime/runtime.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ func registerEVMTokenAddress(batch *storage.QueryBatch, runtime common.Runtime,
127127
addr,
128128
0,
129129
0,
130+
true,
130131
0,
131132
)
132133

@@ -525,13 +526,13 @@ func (m *processor) queueDbUpdates(batch *storage.QueryBatch, data *BlockData) {
525526
// In slow-sync mode, directly update or dead-reckon values.
526527
batch.Queue(
527528
queries.RuntimeEVMTokenDeltaUpsert,
528-
m.runtime, addr, totalSupplyChange, numTransfersChange, lastMutateRound,
529+
m.runtime, addr, totalSupplyChange, numTransfersChange, false, lastMutateRound,
529530
)
530531
} else {
531532
// In fast-sync mode, just record the intent to update the values.
532533
batch.Queue(
533534
queries.RuntimeFastSyncEVMTokenDeltaInsert,
534-
m.runtime, addr, totalSupplyChange, numTransfersChange, lastMutateRound,
535+
m.runtime, addr, totalSupplyChange, numTransfersChange, false, lastMutateRound,
535536
)
536537
}
537538
}

api/spec/v1.yaml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3626,7 +3626,7 @@ components:
36263626

36273627
EvmToken:
36283628
type: object
3629-
required: [contract_addr, eth_contract_addr, num_holders, type, is_verified]
3629+
required: [contract_addr, eth_contract_addr, type, is_verified]
36303630
properties:
36313631
contract_addr:
36323632
type: string
@@ -3675,11 +3675,15 @@ components:
36753675
format: int64
36763676
description: |
36773677
The total number of transfers of this token.
3678+
3679+
May be omitted if the number of transfers cannot be known (e.g. private ERC20 tokens such as BitUSD).
36783680
num_holders:
36793681
type: integer
36803682
format: int64
36813683
description: |
36823684
The number of addresses that have a nonzero balance of this token.
3685+
3686+
May be omited if the number of holders cannot be known (e.g. private ERC20 tokens such as BitUSD).
36833687
example: 123
36843688
ref_swap:
36853689
allOf: [$ref: '#/components/schemas/EvmTokenSwap']

storage/client/client.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2251,6 +2251,7 @@ func (c *StorageClient) RuntimeTokens(ctx context.Context, runtime common.Runtim
22512251
var t EvmToken
22522252
var addrPreimage []byte
22532253
var tokenType common.TokenType
2254+
var likelyNoEvents bool
22542255
var refSwapPairAddr *string
22552256
var refSwap apiTypes.EvmTokenSwap
22562257
var refSwapPairEthAddr []byte
@@ -2270,6 +2271,7 @@ func (c *StorageClient) RuntimeTokens(ctx context.Context, runtime common.Runtim
22702271
&tokenType,
22712272
&t.NebyDerivedPrice,
22722273
&t.NumHolders,
2274+
&likelyNoEvents,
22732275
&refSwapPairAddr,
22742276
&refSwapPairEthAddr,
22752277
&refSwap.FactoryAddress,
@@ -2291,6 +2293,12 @@ func (c *StorageClient) RuntimeTokens(ctx context.Context, runtime common.Runtim
22912293
); err2 != nil {
22922294
return nil, wrapError(err2)
22932295
}
2296+
// If token emits no events (e.g. was added via `additional_evm_token_addresses` and doesn't emit events),
2297+
// we cannot know the number of holders or transfers, so emit those fields.
2298+
if likelyNoEvents {
2299+
t.NumHolders = nil
2300+
t.NumTransfers = nil
2301+
}
22942302

22952303
t.IsVerified = (t.VerificationLevel != nil)
22962304
t.EthContractAddr = EthChecksumAddrFromBarePreimage(addrPreimage)

storage/client/queries/queries.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1221,6 +1221,7 @@ func EVMTokens(rawNames *[]string, args *[]interface{}) string {
12211221
tokens.token_type AS type,
12221222
tokens.neby_derived_price,
12231223
COALESCE(holders.cnt, 0) AS num_holders,
1224+
tokens.likely_no_events,
12241225
ref_swap_pair_creations.pair_address AS ref_swap_pair_address,
12251226
eth_preimage(ref_swap_pair_creations.pair_address) AS ref_swap_pair_address_eth,
12261227
ref_swap_pair_creations.factory_address AS ref_swap_factory_address,

storage/migrations/01_runtimes.up.sql

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,10 @@ CREATE TABLE chain.evm_tokens
337337

338338
num_transfers UINT63 NOT NULL DEFAULT 0,
339339

340+
-- Tokens that likely emit no events and were only added via `additional_evm_token_addresses` will have this set to TRUE.
341+
-- This signals that num_transfers/num_holders values cannot be obtained.
342+
-- likely_no_events BOOLEAN NOT NULL DEFAULT FALSE, -- Added in 46_runtime_evm_tokens_no_events.up.sql.
343+
340344
-- Block analyzer bumps this when it sees the mutable fields of the token
341345
-- change (e.g. total supply) based on dead reckoning.
342346
last_mutate_round UINT63 NOT NULL DEFAULT 0,

storage/migrations/04_fast_sync_temp_tables.up.sql

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ CREATE TABLE todo_updates.evm_tokens( -- Tracks updates to chain.evm_tokens(last
2626
token_address oasis_addr NOT NULL,
2727
total_supply NUMERIC(1000,0) NOT NULL DEFAULT 0,
2828
num_transfers UINT63 NOT NULL DEFAULT 0,
29+
-- Tokens that likely emit no events and were only added via `additional_evm_token_addresses` will have this set to TRUE.
30+
-- This signals that num_transfers/num_holders values cannot be obtained.
31+
-- likely_no_events BOOLEAN NOT NULL DEFAULT FALSE, -- Added in 46_runtime_evm_tokens_no_events.up.sql.
2932
last_mutate_round UINT63 NOT NULL
3033
);
3134
-- Added in 09_fast_sync_temp_transaction_status_updates.up.sql.
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
BEGIN;
2+
3+
ALTER TABLE chain.evm_tokens ADD COLUMN IF NOT EXISTS likely_no_events BOOLEAN NOT NULL DEFAULT FALSE;
4+
5+
ALTER TABLE todo_updates.evm_tokens ADD COLUMN IF NOT EXISTS likely_no_events BOOLEAN NOT NULL DEFAULT FALSE;
6+
7+
COMMIT;

tests/e2e_regression/eden_2025/expected/sapphire_token_by_name.body

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@
77
"is_verified": true,
88
"name": "BitUSDs",
99
"neby_derived_price": "30.025448675228444259",
10-
"num_holders": 0,
11-
"num_transfers": 0,
1210
"ref_token": {
1311
"decimals": 18,
1412
"name": "Wrapped ROSE",

0 commit comments

Comments
 (0)