Conversation
…lidity check at fullnode side.
…rom Did to PublisherDid for the SendTokenDetailsInfo struct; add error message column to Double spenttokenInfo table; handling double spend tokens in all 3 cases where fullnode has already more length token chain, or same length tokenchain or less length tokenchain.
…in fullnodeRBTTable; if synced token is a part token, then checks how many part tokens it's parent token is haviing if it is having more than 2 will add in multiple parenttokensTable.
…r occurs in case of syncing;
…different blockIDs get published in case of regular transfer because of some double spending transaction.
…ock is migrated type in case of token transfer; adding some debug statements in validateSigner function.
…ming block number; added all checks for incoming txnBlock; added a seperate function by putting all 3 checks together; added functions to Validate the token content;
…omes a generic function to validate the token content;
…e changes in GetTokenContentAndValidate function;
…d to the publisher in ProcessRegular transfer; calling ValidateIncomingTokenBlock function in SyncFullTokenChainForFullNode function; modifying GetTokenBlockByNumber function to GetFullNodeTokenBlockByNumber function;
…smart contract and NFTs.
…ypes; handling the token owner check in case of smart contract token;
… to avoid code duplication;
…etest tokens so that local tokens will be having token_level and token_number similar to faucet tokens or mainnet tokens;
… generatetest tokens so that local tokens will be having token_level and token_number similar to faucet tokens or mainnet tokens;" This reverts commit ee02743.
…as a background process;
KryptSai
marked this pull request as ready for review
February 23, 2026 06:24
KryptSai
requested review from
Allen-Cherian,
arnabghose997 and
maneeSHA-256
February 23, 2026 07:05
arnabghose997
requested changes
Feb 23, 2026
arnabghose997
left a comment
Member
There was a problem hiding this comment.
Ensure the errors are returned properly
| if len(elems) < 2 { | ||
| cmd.log.Error(fmt.Sprintf("Invalid token: %v", cmd.token)) | ||
| return | ||
| if cmd.assetType == "rbt" || cmd.assetType == "RBT" { |
Member
There was a problem hiding this comment.
Lets' have only "rbt" as value to denote RBT Asset type
|
|
||
| // If no child tokens exist, return nil (as requested) | ||
| if len(childTokens) == 0 { | ||
| return nil, nil |
Member
There was a problem hiding this comment.
Two scenarios:
- If this condition is expected to return an error, the error should be returned instead of
nil - If this condition is not expected to return an error, instead of returning
nilfor list, an empty list should be returned
| } | ||
|
|
||
| if err := c.w.AddFailedTokensToTable(info); err != nil { | ||
| c.log.Error("Failed to record failed token sync in DB", "token", tokenId, "error", err) |
| c.log.Error("failed to sync token chain for token ", tokenId, "error", err) | ||
| return fmt.Errorf("failed to get latest block for token %s - may need sync", tokenId) | ||
|
|
||
| handled, _ := c.HandleSyncErrorAsDoubleSpent(err, tokenId, newEvent.AssetType, tokenType, newEvent.PublisherDID, previousOwner, txnBlockOwner, fmt.Sprintf("%s, %s both dids are claiming the same token or same did would have double spent the token,dual ownership issue", previousOwner, txnBlockOwner)) |
| incomingBlockID := txnBlockID | ||
| publishersLatestBlockNumber := currentBlockNumber | ||
| //get Fullnode block whose block number is publisher side latest blockID | ||
| fullnodesideBlockBytes, err := c.w.GetFullNodeTokenBlockByNumber(tokenId, tokenType, publishersLatestBlockNumber) |
Member
There was a problem hiding this comment.
The err is not returned here. Please return it
| err := c.ReadTokenContentFromPSQL(tokenId, newEvent.AssetType) | ||
| if err != nil { | ||
| if err := c.AddTokenContentToPSQL(tokenId, newEvent.AssetType); err != nil { | ||
| c.log.Error("failed to add token's ipfs content to psql db, err: %v", err) |
| } | ||
|
|
||
| if err := c.w.AddFailedTokensToTable(info); err != nil { | ||
| c.log.Error("Failed to record failed token sync in DB", "token", tokenId, "error", err) |
Member
There was a problem hiding this comment.
Please return the error here
| } | ||
| // store double spent token info in DoubleSpentTokens table, and remove it from respective tokens table | ||
| err = c.StoreDoubleSpentTokenInfo(doubleSpentTokenInfo) | ||
| if err != nil { |
Member
There was a problem hiding this comment.
error is not returned here
| // Do all 3 checks, If any check fails, handle the failure here also just before adding the block to leveldb. | ||
| err = c.ValidateIncomingTokenBlock(*txnBlock, latestTokenBlock, tokenId, p, newEvent.AssetType) | ||
| if err != nil { | ||
| handled, _ := c.HandleSyncErrorAsDoubleSpent(err, tokenId, newEvent.AssetType, tokenType, newEvent.PublisherDID, previousOwner, txnBlockOwner, fmt.Sprintf("Incoming block %s is wrong,error %v", txnBlockID, err)) |
Member
There was a problem hiding this comment.
error is not returned here
| err = c.ReadTokenContentFromPSQL(tokenId, newEvent.AssetType) | ||
| if err != nil { | ||
| if err := c.AddTokenContentToPSQL(tokenId, newEvent.AssetType); err != nil { | ||
| c.log.Error("failed to add token's ipfs content to psql db, err: %v", err) |
Member
There was a problem hiding this comment.
error is not returned here
…ncErrorAsDoubleSpent function;
…oken genuinity check at quorum side; return error from the HandleSyncErrorAsDoubleSpent handled in processReceivedTokenDetails function;
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
In this PR, we are adding the following validations at fullnode side while syncing them from other nodes.
ex: let's say FullNode is having 10blocks, 11th block it is syncing from other node, then 11th block's previous block ID should be same as existing 10th block's ID.
ex: let's say FullNode is having 10blocks, 11th block it is syncing from other node, then 11th block's senderDID, should be same as existing 10th block's OwnerDID.
Fullnode handles syncing token in the following 3 ways:
Lets say FullNode has 7 blocks of a particular token t1.
In this case, FullNode need to sync the incoming block. So while adding each block to Fullnode's levelDB it checks the above conditions. It will add only the above checks pass.
In this case, Fullnode checks whether is it the same block which is coming or is it the different block. If it is the different block, then it will add it into a double spend tokens table with DID1 &DID2 having the same block.
In this case, Fullnode doesn't need to sync. So it checks whether the incoming block(5th block), is it the same as the 5th block which the FullNode is having, If the Fullnode has a different 5th block than what publisher is publishing, It will add the token to double spend tokens table with DID1 & DID2 as the owners.
More possible exploits but not resolving for now(If we assume all the publisher nodes are under our control, no need to resolve this case):
case description:
let's say nodeA has 8 blocks. A has done double spend transaction, A -> B and A -> B' both with blocknumber 9. Now
B->C, C->D , D->E transactions has happend. So currently E is having 12th block. B' is having 9th block only. When Firstly, if FullNode sync from B', FullNode will get till 9th block. After that if E also publishes tokenchain with length 12. Fullnode checks, previous blockID of the incoming 10th block won't match with the already existing 9th block. so we will note down both DIDs as the same token holder for later reference while giving the tokens to them. If we do in this way any node can simply add a dummy block to their levelDB and publish with a different DID as a publisherDID then Fullnode treat it as a double spend transaction and note down both DIDs to distribute the tokens later.
Some more checks to discuss: