Skip to content

Extended RPC Method Support and Block Payload Enhancement #6126

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

Closed
blockketten opened this issue Dec 18, 2024 · 35 comments
Closed

Extended RPC Method Support and Block Payload Enhancement #6126

blockketten opened this issue Dec 18, 2024 · 35 comments

Comments

@blockketten
Copy link

Background

Tron’s VM supports most of the features of modern solidity and it would be possible for us to build products on Tron in a similar fashion to what we do on EVM chains but most modern development tools do not work with Tron. Most of the differences lay at the RPC level, making it very hard to run core security tests (fork tests are not possible using Foundry, just basic forks do not work either)

Forking is a hard technical requirement for us, we need to be able to perform tests on our contracts with live state to ensure things are working properly. Currently we haven’t found any solution to get a fork (even tenderly has no support for tron unfortunately), so we tried to perform these manually using anvil / forge.

We found that Foundry is unable to perform the fork tests due to some diffs in the returned payload by the json RPCs.

Methods required to fork

By running fork tests on eth mainnet behind a proxy, we identified most of the methods required to perform them

eth_chainId
eth_gasPrice
eth_getBlockByNumber
eth_getStorageAt
eth_getBalance
eth_getTransactionCount
eth_getCode
eth_blockNumber

Unfortunately, Foundry is unable to work with Tron’s RPCs, as unmarshalling data returned by the endpoint fails.

anvil --fork-url https://powerful-polished-gas.tron-mainnet.quiknode.pro/xxx/jsonrpc

Error: failed to get fork block number

Caused by:
   0: deserialization error: Invalid string length at line 1 column 26801
   1: Invalid string length at line 1 column 26801

Location:
    /Users/runner/work/foundry/foundry/crates/anvil/src/config.rs:1154:18

Probable root cause

After some digging, we identified the possible root cause for this. The block payload from the tron rpc is lacking the stateRoot field content, which is always equal to 0x

This single field could be the only reason why some of the Foundry tools are not working properly and crashing whenever some block payloads are deserialized.

curl --location 'https://api.trongrid.io/jsonrpc' --header 'Content-Type:application/json' --data '{
    "jsonrpc": "2.0",
    "method": "eth_getBlockByNumber",
    "params": ["latest", true],
    "id": 1
}' | jq .result
{
  "baseFeePerGas": "0x0",
  "difficulty": "0x0",
  "extraData": "0x",
  "gasLimit": "0x160227b88",
  "gasUsed": "0x360d92",
  "hash": "0x00000000040a0687e0fc7194aabd024a4786ce94ad63855774f8d48896d8750b",
  "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  "miner": "0x9a96c8003a1e3a6866c08acff9f629e2a6ef062b",
  "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
  "nonce": "0x0000000000000000",
  "number": "0x40a0687",
  "parentHash": "0x00000000040a068652c581a982a0d17976201ad44aa28eb4e24881e82f99ee04",
  "receiptsRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
  "sha3Uncles": "0x0000000000000000000000000000000000000000000000000000000000000000",
  "size": "0xba05",
  "stateRoot": "0x", // foundry is probably expecting a bytes32 here
  "timestamp": "0x6759f2f1",
  "totalDifficulty": "0x0",
  "transactions": [...]
}

Mocking the stateRoot

To move further in our testing, we used mitmproxy to proxy all requests made to the RPC and manually mock the stateRoot in the eth_getBlockByNumber queries. We now hit another issue

anvil --fork-url http://localhost:8080
Error: failed to create genesis

Caused by:
    failed to get account for 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266: server returned an error response: error code -32601: the method eth_getTransactionCount does not exist/is not available, data: "{}"

Location:
    /Users/runner/work/foundry/foundry/crates/anvil/src/eth/backend/mem/mod.rs:345:39

The eth_getTransactionCount is not defined on the tron RPC.

Mocking the transaction count result

Next step is now to intercept eth_getTransactionCount methods and return a mocked value. We hit another core issue when the eth_getCode query is made

anvil --fork-url http://localhost:8080
Error: failed to create genesis

Caused by:
    failed to get account for 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266: server returned an error response: error code -32602: QUANTITY not supported, just support TAG as latest, data: "{}"

Location:
    /Users/runner/work/foundry/foundry/crates/anvil/src/eth/backend/mem/mod.rs:345:39

When replaying these queries manually, we can see that the method is unable to support arbitrary block tag values for the getCode query (only supports latest )

curl --location https://powerful-polished-gas.tron-mainnet.quiknode.pro/xxx/jsonrpc --header 'Content-Type:application/json' --data '{
    "jsonrpc": "2.0",
    "method": "eth_getCode",
    "params": ["0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", "0x1234"],
    "id": 1
}'
{"jsonrpc":"2.0","id":1,"error":{"code":-32602,"message":"QUANTITY not supported, just support TAG as latest","data":"{}"}}

Deep state management issue

It seems that most issues are coming from the ability for the tron rpc nodes to retrieve state specific data. First, the inability to provide a stateRoot in the block body shows that there might be a completely different state handling from what the evm chains are used to do.

Same thing for eth_getCode where we are completely unable to retrieve anything that is not at the tip of the chain.

Rationale

Fork testing is essential for secure smart contract development as, it allows testing contracts against live network state. Currently, industry-standard tools like Foundry cannot perform fork tests on Tron due to RPC limitations, limiting the ecosystem development of Tron.

Use cases:

  • Security testing of smart contracts against production state
  • Integration testing with existing protocols
  • Local development environment that mirrors mainnet
  • Automated testing pipelines

Specification

The following features are requested in the RPC implementation for Tron:

Block Payload Enhancement

  • Add proper stateRoot field in block responses (currently returns "0x")

Extended RPC Method Support

  • Implement full eth_getTransactionCount functionality
  • Add support for arbitrary block tags in eth_getCode (currently only supports "latest")

Test Specification

Success criteria:

  1. Foundry's anvil should successfully fork Tron mainnet
  2. Fork tests should execute without deserialization errors
  3. Historical state queries should return accurate data

Scope Of Impact

  • Smart contract development workflows
  • Testing frameworks and tools
  • Security audit processes

Implementation

The Kiln team is willing to help test and provide feedback during implementation.

@simbadMarino
Copy link

Hello Kiln team, thanks!

tronprotocol devs: Please help us supporting Kiln on this feature as this is a roadblock for several enterprise-grade platforms to enable TRON Staking capabilities like Fireblocks, Ledger Enterprise, VanEck, TRUST, etc .

Let's discuss potential solutions and what would be the best to increase TRON interoperability further :)

@317787106
Copy link
Contributor

317787106 commented Dec 19, 2024

@blockketten Let's discuss the eth_getBlockByNumber API. Since TRON does not have a stateRoot, we currently set its value to "0x". Would you prefer extending it to "0x000...0" (a 32-byte length value)? This change might impact other developers as well.

@317787106
Copy link
Contributor

317787106 commented Dec 19, 2024

@blockketten In Ethereum JSON-RPC, the method eth_getTransactionCount refers to the total transaction count of a specific owner address. However, due to the limitations of TRON's data structure, we are unable to calculate this for each address in real-time. As a result, this method is not supported.

What are your suggestions for addressing this limitation?

@Federico2014
Copy link
Contributor

@blockketten Thank you for your suggestions. We will consider implementing Tron's Mainnet forking testing tool. It is quite necessary.

@317787106
Copy link
Contributor

317787106 commented Dec 19, 2024

@blockketten Let's discuss the eth_getCode API. Since TRON does not maintain a state trie, we can only query data from the latest database. When a specific block number (i.e., QUANTITY) is specified, it refers to historical data, which we are unable to query. This limitation applies to all other APIs as well.

@blockketten
Copy link
Author

Thank you for your answers, @317787106 and @Federico2014! In the Tron developer docs, it states that Tron does maintain a state trie. Can you clarify what you mean when you say that it does not maintain a state trie? Also, what are the precise limitations of the Tron data structure that prevent real time accounting of address transaction counts?

@Federico2014 Do you mean that you will implement forking functionality into TronBox? If so, how can we track progress on this?

@317787106
Copy link
Contributor

@blockketten The column accountStateRoot in BlockHeader is empty now. We don't have an index of user-initiated transactions in leveldb, so it's impossible to calculate the amount, you can only get it from Tronscan.

@Federico2014
Copy link
Contributor

@blockketten We plan to implement this fork function first through command line tools to confirm its feasibility. After that, we will communicate with the Tronbox team to support this function. However, it is still in the early stages. After we sort out the relevant information recently, we will make a schedule, and update the progress on the issues of the java-tron ​​project.

@simbadMarino
Copy link

@Federico2014 is there an ETA for at least a Beta release of the fork function so Kiln and other teams can begin testing?

@Federico2014
Copy link
Contributor

@simbadMarino We will try our best to make the fork CLI tool available in the next release of java-tron. The specific date is not confirmed yet.

@simbadMarino
Copy link

Thanks @Federico2014 ! This will greatly increase TRON's interoperability. Kudos to the team for prioritizing this feature! :) Happy New Year, everyone!

@angrynurd
Copy link

To support fork testing, does Tron require significant architectural changes, and how will these changes impact the existing Tron network and smart contracts?

@Federico2014
Copy link
Contributor

@endiaoekoe It doesn't require architectural changes. We will add the fork tool in the Toolkit, which does not influence the existing Tron network and smart contracts.

@angrynurd
Copy link

@blockketten
I really like this feature.
Could you please let me know the latest progress on this functionality? I'm very much looking forward to trying out this new feature, even if it's not complete yet.

@Federico2014
Copy link
Contributor

@blockketten @simbadMarino @angrynurd We have added the shadow fork tool in tron-docker, please refer to the guidance and try it. If you have any problems, please tell us in time.

@pegahcarter
Copy link

+1 on the importance of this issue. As Tron is EVM-like, it needs to support EVM tooling if it is to see continued legitimate development. Fork testing is a basic essential to an EVM development stack.

@Federico2014 can the docker requirements be abstracted away so that users call a single tron-hosted rpc with a block height argument? Fork testing should be IMO provided by the chain, not a burden on devs.

@Federico2014
Copy link
Contributor

@pegahcarter You are right, fork testing should not be on devs. But I am afraid it is not feasible to use a single tron-hosted rpc. Fork testing should satisfy diversified demands. We may need further research.

@simbadMarino
Copy link

Hello guys, circling back here, is this the right feature branch to track stateRoot implementation into TRON's JSON-RPC compatible API?

If yes, do you have an ETA for it to be ready? This would significantly improve TRON's compatibility with the broader web3 ecosystem.

If no, would you please point to the right PR if available?

Thanks a lot !

@CodeNinjaEvan @halibobo1205 @Federico2014

@halibobo1205
Copy link
Contributor

Yes, this branch state-trie is archived data. Unlike ETH, Tron's stateRoot is non-consensual, and Tron implements a switch to turn it on itself at any height.
This branch is currently under experimental development. @simbadMarino

@simbadMarino
Copy link

Thanks, @halibobo1205, for the confirmation. I have some additional questions:

  1. Once the state-trie feature reaches a mature stage, will a separate "archive node" node type be created?
  2. If yes, will this new node type provide the missing stateRoot data for all relevant JSON-RPC methods?, including:
  • eth_getBalance
  • eth_getCode
  • eth_getStorageAt
  • eth_call
  • eth_getProof
  • eth_getTransactionCount

Thanks!

@halibobo1205
Copy link
Contributor

@simbadMarino, eth_getProof and eth_getTransactionCount won't support it for a while.

@simbadMarino
Copy link

Thanks for the heads up @halibobo1205 , do you have any estimation on getting this out the experimental phase?

@halibobo1205
Copy link
Contributor

The archive node is still under development, and its current implementation is not as comprehensive as Ethereum. May I ask what your main requirements are for the archive node? Are you looking for historical state queries? @simbadMarino

@simbadMarino
Copy link

simbadMarino commented Apr 11, 2025

Yes @halibobo1205 , historical state queries, ideally, we'd like to have the JSON-RPC on TRON to match the Ethereum one, a major blocker for EVM dev tooling to integrate TRON relies on the stateRoot field missing on TRON (Arbitrary Block Number parameter).

I did some comparison between TRON and Ethereum for missing and partially implemented JSON-RPC methods and got the following table:

Image

Source: https://github.com/simbadMarino/ethereum-tron-json-rpc/blob/tron/src/data/TRON%20methods.md

After asking some partners like Kiln, thegraph and others, the most critical ones to fully implement are:

  • eth_getBalance
  • eth_getCode
  • eth_getStorageAt
  • eth_call
  • eth_getProof
  • eth_getTransactionCount
  • debug_traceCall
  • eth_getBlockReceipts

If we do we are effectively closing some major gaps we've been having in TRON in terms of EVM interoperability, meaning we will be able to easily build on top of already existing popular dev tools and infrastructure, services and SDK. This will speed up TRON integration, reduce integration costs and overall improving the dev experience when building on TRON.

I hope this helps to clarify further :)

Thanks again for the support!

@halibobo1205
Copy link
Contributor

@simbadMarino For the following four methods, we will conduct detailed research to evaluate whether they can be supported: cc @waynercheung

  • eth_getProof
  • eth_getTransactionCount
  • debug_traceCall
  • eth_getBlockReceipts

@blockketten blockketten changed the title Extended RPC Method Support and Block Payload Enhancement to enable fork testing Extended RPC Method Support and Block Payload Enhancement Apr 16, 2025
@halibobo1205 halibobo1205 moved this from In progress to Todo in java-tron Apr 22, 2025
@halibobo1205
Copy link
Contributor

@blockketten @simbadMarino @angrynurd We have added the shadow fork tool in tron-docker, please refer to the guidance and try it. If you have any problems, please tell us in time.

Can this be marked as done? @Federico2014 @blockketten

@simbadMarino
Copy link

@halibobo1205, can we use this issue to track missing important JSON-RPC methods? I believe there's no other issue tracking this particular topic.

@waynercheung
Copy link
Contributor

@halibobo1205, can we use this issue to track missing important JSON-RPC methods? I believe there's no other issue tracking this particular topic.

Hi @simbadMarino , so till now, the most critical JSON-RPC to fully implement as below:

  • eth_getBalance
  • eth_getCode
  • eth_getStorageAt
  • eth_call
  • eth_getProof
  • eth_getTransactionCount
  • debug_traceCall
  • eth_getBlockReceipts

And the following apis still need detailed research to check if can be implemented in the archive node:

  • eth_getProof
  • eth_getTransactionCount
  • debug_traceCall
  • eth_getBlockReceipts

right?

@Federico2014
Copy link
Contributor

Can this be marked as done? @Federico2014 @blockketten

@halibobo1205 I think so.

@simbadMarino
Copy link

simbadMarino commented Apr 23, 2025

@halibobo1205, can we use this issue to track missing important JSON-RPC methods? I believe there's no other issue tracking this particular topic.

Hi @simbadMarino , so till now, the most critical JSON-RPC to fully implement as below:

  • eth_getBalance
  • eth_getCode
  • eth_getStorageAt
  • eth_call
  • eth_getProof
  • eth_getTransactionCount
  • debug_traceCall
  • eth_getBlockReceipts

And the following apis still need detailed research to check if can be implemented in the archive node:

  • eth_getProof
  • eth_getTransactionCount
  • debug_traceCall
  • eth_getBlockReceipts

right?

correct @waynercheung

@waynercheung
Copy link
Contributor

@simbadMarino How about tracking this issue on #6289?

@simbadMarino
Copy link

Sounds good @waynercheung , lets track it in #6289

@u59149403
Copy link

I implemented JSON-RPC proxy for making TRON more Ethereum-compatible. Currently very few features are supported. Check it here: https://github.com/u59149403/tjrp

@waynercheung
Copy link
Contributor

I implemented JSON-RPC proxy for making TRON more Ethereum-compatible. Currently very few features are supported. Check it here: https://github.com/u59149403/tjrp

@u59149403 , Thank you for the thoughtful suggestion! Implementing a proxy layer (e.g., a gateway or using OpenResty with Lua) to enhance compatibility for unsupported features is indeed a promising approach.

However, this falls outside the scope of the java-tron project itself and is better suited for discussion in a separate community or implementation space.

@waynercheung
Copy link
Contributor

Sounds good @waynercheung , lets track it in #6289

ok, this issue maybe closed later.

@github-project-automation github-project-automation bot moved this from Todo to Done in java-tron May 28, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Done
Development

No branches or pull requests

10 participants