-
-
Notifications
You must be signed in to change notification settings - Fork 745
fix(tron): the receipt for unsolidified block should not be set to ni… #1583
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from 6 commits
edd3f34
72a1191
cae749d
dd1b64d
a5da37d
f2115fc
a886dc6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -287,6 +287,16 @@ func (b *TronRPC) GetBestBlockHash() (string, error) { | |
|
|
||
| // GetBlockHash returns block hash in Tron API format (without 0x prefix). | ||
| func (b *TronRPC) GetBlockHash(height uint32) (string, error) { | ||
| if b.isBlockSolidified(uint64(height)) && b.solidityNodeHTTP != nil { | ||
| ctx, cancel := context.WithTimeout(b.requestContext(), b.Timeout) | ||
| defer cancel() | ||
| hash, err := b.requestBlockHashByNum(ctx, height) | ||
| if err == nil { | ||
| return hash, nil | ||
| } | ||
| glog.V(1).Infof("Tron native getblock hash lookup failed for height %d, falling back to JSON-RPC: %v", height, err) | ||
| } | ||
|
|
||
| hash, err := b.EthereumRPC.GetBlockHash(height) | ||
| if err != nil { | ||
| return "", err | ||
|
|
@@ -347,21 +357,6 @@ func (b *TronRPC) GetBlockInfo(hash string) (*bchain.BlockInfo, error) { | |
| } | ||
|
|
||
| func (b *TronRPC) getBestHeader() (bchain.EVMHeader, error) { | ||
| // During initial sync (before ZeroMQ is initialized) there is no push-based | ||
| // tip refresh, so always read the latest header from the backend. | ||
| if b.mq == nil { | ||
| _, err := b.refreshBestHeaderFromChain() | ||
| if err != nil { | ||
| return nil, err | ||
| } | ||
| b.bestHeaderLock.Lock() | ||
| defer b.bestHeaderLock.Unlock() | ||
| if b.bestHeader == nil || b.bestHeader.Number() == nil { | ||
| return nil, errors.New("best header is nil") | ||
| } | ||
| return b.bestHeader, nil | ||
| } | ||
|
|
||
| b.bestHeaderLock.Lock() | ||
| cachedHeader := b.bestHeader | ||
| cachedAt := b.bestHeaderTime | ||
|
|
@@ -384,22 +379,6 @@ func (b *TronRPC) getBestHeader() (bchain.EVMHeader, error) { | |
| return b.bestHeader, nil | ||
| } | ||
|
|
||
| // setBestHeader stores h as the cached tip and reports whether it changed. | ||
| // | ||
| // Unlike EthereumRPC.setBestHeader this is intentionally NON-monotonic: a lower | ||
| // height is accepted. Tron's tip is never taken from the feed header (the ZeroMQ | ||
| // notification carries none) — it is always an HTTP re-query (refreshBestHeaderFromChain), | ||
| // refreshed on every notification and on a tronBestHeaderMaxAge timer, so the cache | ||
| // is meant to track whatever the backend currently reports. Accepting a lower height | ||
| // is what lets a genuine rollback surface immediately to resyncIndex, so Tron is not | ||
| // subject to the frozen-tip masking that the EVM monotonic guard introduces (and which | ||
| // EVM has to undo with a watchdog regress). | ||
| // | ||
| // Tradeoff: with a load-balanced Tron RPC, a single lagging node answering a re-query | ||
| // could regress the tip and trip a spurious fork in resyncIndex (the case the EVM | ||
| // monotonic guard exists to prevent). That is acceptable for the common single-node | ||
| // java-tron backend; if Tron is ever fronted by a load balancer, port the EVM pattern | ||
| // here (monotonic hot path + on-advance liveness + allowRegress watchdog poll). | ||
| func (b *TronRPC) setBestHeader(h bchain.EVMHeader) bool { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This branch deleted the doc comment that explained |
||
| if h == nil || h.Number() == nil { | ||
| return false | ||
|
|
@@ -697,11 +676,11 @@ func (b *TronRPC) computeBlockConfirmations(blockNumber uint64) (uint32, error) | |
| return uint32(bestHeight - blockNumber + 1), nil | ||
| } | ||
|
|
||
| func (b *TronRPC) buildTxFromHTTPData(txByID *tronGetTransactionByIDResponse, txInfo *tronGetTransactionInfoByIDResponse, blockTime int64, confirmations uint32, internalData *bchain.EthereumInternalData, isSolidified bool) (*bchain.Tx, error) { | ||
| func (b *TronRPC) buildTxFromHTTPData(txByID *tronGetTransactionByIDResponse, txInfo *tronGetTransactionInfoByIDResponse, blockTime int64, confirmations uint32, internalData *bchain.EthereumInternalData, keepReceipt bool) (*bchain.Tx, error) { | ||
| csd := tronBuildEthereumSpecificData(txByID, txInfo) | ||
| csd.InternalData = internalData | ||
|
|
||
| if !isSolidified { | ||
| if !keepReceipt { | ||
| csd.Receipt = nil // set to nil so it can be considered as pending | ||
| } | ||
|
|
||
|
|
@@ -948,7 +927,9 @@ func (b *TronRPC) GetBlock(hash string, height uint32) (*bchain.Block, error) { | |
| txInternalData = &internalData[i] | ||
| } | ||
|
|
||
| rebuiltTx, err := b.buildTxFromHTTPData(txByID, txInfo, bbh.Time, confirmations, txInternalData, isSolidified) | ||
| // Keep receipts for block indexing even before solidity. If logs are dropped | ||
| // here, token-transfer participants never reach the address/contract indexes. | ||
| rebuiltTx, err := b.buildTxFromHTTPData(txByID, txInfo, bbh.Time, confirmations, txInternalData, true) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This fixes the indexing path, but the serving path stays asymmetric: |
||
| if err != nil { | ||
| return nil, err | ||
| } | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Heads-up on the removed
if b.mq == nil { refreshBestHeaderFromChain() }block:getBestHeadernow serves a cached tip for up totronBestHeaderMaxAge(30s), and the watchdog that refreshes it only starts inInitializeMempool, which runs after the initialResyncIndex. So during initial bulk sync (and in polling-only mode before mempool init) the target tip andcomputeBlockConfirmationscan lag the chain by up to 30s where they were previously always fresh. This looks like the deliberate trade-off from the "reduce requests per block" commit and is benign for far-behind sync — just confirming it's intended and that the syncer can't briefly treat the stale tip as fully-synced.