From 14a331133da826440aa027e606afef6affd0a9cc Mon Sep 17 00:00:00 2001 From: Warren He Date: Mon, 18 Dec 2023 14:56:13 -0800 Subject: [PATCH] runtime: fix owner update for burned NFT instances --- analyzer/queries/queries.go | 18 ++++++++++++------ analyzer/runtime/extract.go | 8 ++++++-- analyzer/runtime/runtime.go | 17 +++++++++++++++-- 3 files changed, 33 insertions(+), 10 deletions(-) diff --git a/analyzer/queries/queries.go b/analyzer/queries/queries.go index 022e1cdae..e9d61af0b 100644 --- a/analyzer/queries/queries.go +++ b/analyzer/queries/queries.go @@ -715,13 +715,19 @@ var ( RuntimeEVMNFTUpsert = ` INSERT INTO chain.evm_nfts AS old - (runtime, token_address, nft_id, owner, num_transfers, last_want_download_round) + (runtime, token_address, nft_id, num_transfers, last_want_download_round) VALUES - ($1, $2, $3, $4, $5, $6) - ON CONFLICT (runtime, token_address, nft_id) DO UPDATE - SET - owner = COALESCE(excluded.owner, old.owner), - num_transfers = old.num_transfers + excluded.num_transfers` + ($1, $2, $3, 0, $4) + ON CONFLICT (runtime, token_address, nft_id) DO NOTHING` + + RuntimeEVMNFTUpdateTransfer = ` + UPDATE chain.evm_nfts SET + owner = $4, + num_transfers = num_transfers + $5 + WHERE + runtime = $1 AND + token_address = $2 AND + nft_id = $3` RuntimeEVMNFTAnalysisStale = ` SELECT diff --git a/analyzer/runtime/extract.go b/analyzer/runtime/extract.go index 813c97ff1..02f5c5069 100644 --- a/analyzer/runtime/extract.go +++ b/analyzer/runtime/extract.go @@ -121,7 +121,11 @@ type NFTKey struct { } type PossibleNFT struct { - NewOwner *apiTypes.Address + // NewOwner has the latest owner if .NumTransfers is more than zero. If + // the last transfer burned this NFT instance, then it's the empty string. + NewOwner apiTypes.Address + // NumTransfers is how many times we saw it transferred. If it's more than + // zero, the new owner is in .NewOwner. NumTransfers int } @@ -270,7 +274,7 @@ func registerNFTExist(nftChanges map[NFTKey]*PossibleNFT, contractAddr apiTypes. func registerNFTTransfer(nftChanges map[NFTKey]*PossibleNFT, contractAddr apiTypes.Address, tokenID *big.Int, newOwner apiTypes.Address) { possibleNFT := findPossibleNFT(nftChanges, contractAddr, tokenID) possibleNFT.NumTransfers++ - possibleNFT.NewOwner = &newOwner + possibleNFT.NewOwner = newOwner } func findTokenChange(tokenChanges map[TokenChangeKey]*big.Int, contractAddr apiTypes.Address, accountAddr apiTypes.Address) *big.Int { diff --git a/analyzer/runtime/runtime.go b/analyzer/runtime/runtime.go index 311aae7f4..fa6181c28 100644 --- a/analyzer/runtime/runtime.go +++ b/analyzer/runtime/runtime.go @@ -14,6 +14,7 @@ import ( "github.com/oasisprotocol/nexus/analyzer/queries" evm "github.com/oasisprotocol/nexus/analyzer/runtime/evm" uncategorized "github.com/oasisprotocol/nexus/analyzer/uncategorized" + apiTypes "github.com/oasisprotocol/nexus/api/v1/types" "github.com/oasisprotocol/nexus/common" "github.com/oasisprotocol/nexus/config" "github.com/oasisprotocol/nexus/log" @@ -399,9 +400,21 @@ func (m *processor) queueDbUpdates(batch *storage.QueryBatch, data *BlockData) { m.runtime, key.TokenAddress, key.TokenID, - possibleNFT.NewOwner, - possibleNFT.NumTransfers, data.Header.Round, ) + if possibleNFT.NumTransfers > 0 { + var newOwner *apiTypes.Address + if possibleNFT.NewOwner != "" { + newOwner = &possibleNFT.NewOwner + } + batch.Queue( + queries.RuntimeEVMNFTUpdateTransfer, + m.runtime, + key.TokenAddress, + key.TokenID, + newOwner, + possibleNFT.NumTransfers, + ) + } } }