跳到主要内容

运行轻节点

Note: Currently, eSpace (EVM full-compatible space) RPC methods are not supported on the Conflux Light Node.

概览

Node version: conflux-rust v2.1.0.

Light nodes are special nodes in the Conflux network that store block headers only and retrieve everything else from their peers on-demand. This means that by default light nodes do not store transactions nor do they store state trees either. This can drastically reduce the disk and bandwidth use of light nodes compared to full and archive nodes, especially under high TPS. As a trade-off RPC queries have a higher latency on light nodes.

Light nodes execute GHAST consensus on their local header graph and they also verify each item retrieved on-demand using Merkle proofs and other similar mechanisms. Items retrieved on-demand include accounts, bloom filters, transactions, and transaction receipts. While light nodes need to rely on their peers to fulfill RPC queries they do this in a trustless way.

The current light node implementation is still considered experimental therefore bugs are expected to exist. If you encounter any issues please let us know by opening an issue on the conflux-rust repository.

Running a light node

Light nodes can be enabled in the hydra.toml settings file (testnet.toml for testnet) in the node_type variable.

node_type = "light"

Alternatively Light nodes can be enabled using the --light command line flag:

Start by downloading the latest release from the conflux-rust repository or by building from source code following this guide. Then, you can simply run the node using these commands:

> cd run
> ./conflux --config hydra.toml

Similarly to full nodes you will know when your node is fully synced with the network once the console prints:

Catch-up mode: false

Interacting with a light node

Similarly to full and archive nodes, you can interact with a light node through an HTTP, TCP, or WebSocket connection. By default local HTTP queries are enabled through port 12539. For details, please refer to the JSON-RPC documentation.

RPC queries

Light nodes support most Conflux RPC APIs and support for the rest is also on the way. As light nodes need to query their peers to fulfill RPC requests, the overall latency is slightly larger. (It is significantly larger for cfx_getLogs.)

> curl -X POST --data '{ "jsonrpc": "2.0", "method": "cfx_clientVersion", "id": 1 }' -H "Content-Type: application/json" localhost:12539
{ "jsonrpc": "2.0", "result": "conflux-rust-1.0.0", "id": 1 }

> curl -X POST --data '{ "jsonrpc":"2.0", "method":"cfx_getBalance", "params": ["cfx:type.user:aarc9abycue0hhzgyrr53m6cxedgccrmmyybjgh4xg"], "id": 2 }' -H "Content-Type: application/json" localhost:12539
{ "jsonrpc": "2.0", "result": "0x5fc346d4363f84249d4a", "id": 2 }

> curl -X POST --data '{ "jsonrpc": "2.0", "method": "cfx_getLogs", "params": [{ "address": "cfx:type.contract:acc7uawf5ubtnmezvhu9dhc6sghea0403y2dgpyfjp", "fromEpoch": "0x1c8b8", "toEpoch": "0x1c8d6" }], "id": 3}' -H "Content-Type: application/json" localhost:12539
{ "jsonrpc": "2.0", "result": [{ "address": "CFX:TYPE.CONTRACT:ACC7UAWF5UBTNMEZVHU9DHC6SGHEA0403Y2DGPYFJP", "blockHash": "0x694898c77602511b6c411860ec230ac7ca58c08a4cbe3cad904e724b2eb97fee", "data": "0x0000000000000000000000000000000000000000000000049b9ca9a694340000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000141da5f533abef1b82a4a6d698415b8a56894b7b410000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "epochNumber": "0x1c8bf", "logIndex": "0x0", "topics": ["0x06b541ddaa720db2b10a4d0cdac39b8d360425fc073085fac19bc82614677987","0x0000000000000000000000001da5f533abef1b82a4a6d698415b8a56894b7b41","0x0000000000000000000000001da5f533abef1b82a4a6d698415b8a56894b7b41","0x00000000000000000000000080bb30efc5683758128b404fe5da03432eb16634"], "transactionHash": "0x7dcfeb245369e509f2d154f2d5523e3ebe0b54f1d420e02edf56c70cdcae278d", "transactionIndex": "0x0", "transactionLogIndex": "0x0" },{ "address": "CFX:TYPE.CONTRACT:ACC7UAWF5UBTNMEZVHU9DHC6SGHEA0403Y2DGPYFJP", "blockHash": "0x694898c77602511b6c411860ec230ac7ca58c08a4cbe3cad904e724b2eb97fee", "data": "0x0000000000000000000000000000000000000000000000049b9ca9a694340000", "epochNumber": "0x1c8bf", "logIndex": "0x1", "topics": ["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef","0x0000000000000000000000001da5f533abef1b82a4a6d698415b8a56894b7b41","0x00000000000000000000000080bb30efc5683758128b404fe5da03432eb16634"], "transactionHash": "0x7dcfeb245369e509f2d154f2d5523e3ebe0b54f1d420e02edf56c70cdcae278d", "transactionIndex": "0x0", "transactionLogIndex": "0x1" }], "id": 3 } -H "Content-Type: application/json" localhost:12539

JavaScript

Light nodes support most of the functionalities of the JavaScript SDK (js-conflux-sdk). You can install the SDK using the following command:

npm install --save js-conflux-sdk

Then, you can query the blockchain and send transactions:

const { Conflux, Drip } = require('js-conflux-sdk');

const PRIVATE_KEY = '0x...';
const RECEIVER = 'cfx:aarc9abycue0hhzgyrr53m6cxedgccrmmyybjgh4xg';

async function main() {
const conflux = new Conflux({ url: 'http://localhost:12539' });

// query node version
const client_version = await conflux.provider.call('cfx_clientVersion');
console.log('client_version:', client_version);

// query account balance
const balance = await conflux.getBalance('cfx:type.user:aarc9abycue0hhzgyrr53m6cxedgccrmmyybjgh4xg');
console.log('balance:', balance.toString(10));

// query smart contract logs
const logs = await conflux.getLogs({
address: 'cfx:type.contract:acc7uawf5ubtnmezvhu9dhc6sghea0403y2dgpyfjp',
fromEpoch: 116920,
toEpoch: 116950,
});

console.log('logs:', logs);

// send transaction
const account = conflux.wallet.addPrivateKey(PRIVATE_KEY);

const tx = {
from: account.address,
to: RECEIVER,
value: Drip.fromCFX(0.1),
gasPrice: 1000000000,
};

try {
const receipt = await conflux.sendTransaction(tx).executed();
console.log('receipt:', receipt);
} catch (e) {
console.error(e);
}
}

main();

Other SDKs

While it has not been tested, light nodes are expected to work with the Java, Python and Go SDKs as well.

Troubleshooting

Why do I get an error when calling a contract method?

If you run the following code:

const admin = await cfx.InternalContract('AdminControl').getAdmin('cfx:type.contract:acc7uawf5ubtnmezvhu9dhc6sghea0403y2dgpyfjp');
console.log('admin:', admin);

...You will get this error:

RPCError: This API is not implemented yet
at HttpProvider.call
at processTicksAndRejections
at async Conflux.call
at async MethodTransaction.call
at async MethodTransaction.then {
code: -32000,
data: 'Tracking issue: https://github.com/Conflux-Chain/conflux-rust/issues/1461'
}

This is because contract calls use the cfx_call RPC API which is not yet supported on light nodes.

Suppose you would like to send a transaction to a smart contract:

conflux.InternalContract('AdminControl').setAdmin('cfx:type.contract:acc7uawf5ubtnmezvhu9dhc6sghea0403y2dgpyfjp', 'cfx:type.user:aarc9abycue0hhzgyrr53m6cxedgccrmmyybjgh4xg').sendTransaction({
from: account,
}).executed();

You will get a similar error. This is because for contract transactions, js-conflux-sdk will automatically attempt to estimate the gas limit and storage limit using the cfx_estimateGasAndCollateral RPC which is not yet supported on light nodes. You can address this by manually setting these parameters:

conflux.InternalContract('AdminControl').setAdmin('cfx:type.contract:acc7uawf5ubtnmezvhu9dhc6sghea0403y2dgpyfjp', 'cfx:type.user:aarc9abycue0hhzgyrr53m6cxedgccrmmyybjgh4xg').sendTransaction({
from: account,
gas: 1000000000,
storageLimit: '0x0',
gasPrice: '0x1',
}).executed();

If you encounter a This API is not implemented yet error, you can set the debug logger on the conflux object to find out which RPC is causing it.

const cfx = new Conflux({
url: 'http://localhost:12539',
logger: console,
});

Why do I see timeout instead of null

For most operations, you might sometimes see a timeout error:

RPCError: Operation timeout: "Timeout while retrieving transaction with hash 0x497755f45baef13a35347933c48c0b8940f2cc3347477b5ed9f165581b082699"

This is because light nodes have to retrieve transactions and other items from their peers. If no peer responds within 4 seconds, you will get a timeout error. In most cases, retrying the query will succeed.

You will also get a timeout if you call conflux.getTransactionByHash and pass a transaction hash that does not exist. This is because the "non-existence" or transactions is not something light nodes can verify, so returning null might be misleading. This behavior might change in the future.

I'm searching through event logs, why is it so slow?

Log filtering is a very expensive operation on light nodes. For each epoch in the range you specify, the node needs to perform 1 to 3 queries. We recommend you make multiple queries with smaller epoch ranges.

instead of:

const fromEpoch = 110000;
const toEpoch = 119999;

// NOT RECOMMENDED
const logs = await cfx.getLogs({ fromEpoch, toEpoch, address: 'cfx:type.contract:acc7uawf5ubtnmezvhu9dhc6sghea0403y2dgpyfjp' });
console.log('logs:', logs);

You are encouraged to do this:

for (ii = 0; ii < 10; ++ii) {
const fromEpoch = 110000 + ii * 1000;
const toEpoch = 110000 + (ii + 1) * 1000 - 1;
const logs = await cfx.getLogs({ fromEpoch, toEpoch, address: 'cfx:type.contract:acc7uawf5ubtnmezvhu9dhc6sghea0403y2dgpyfjp' });
console.log('logs:', logs);
}

RPC availability

RPCstatus
cfx_call❌ Not supported yet
cfx_checkBalanceAgainstTransaction✅ Supported
cfx_clientVersion✅ Supported
cfx_epochNumber✅ Supported
cfx_estimateGasAndCollateral❌ Not supported yed
cfx_gasPrice✅ Supported
cfx_getAccount✅ Supported
cfx_getAccumulateInterestRate✅ Supported
cfx_getAdmin✅ Supported
cfx_getBalance✅ Supported
cfx_getBestBlockHash✅ Supported
cfx_getBlockByEpochNumber✅ Supported
cfx_getBlockByHash✅ Supported
cfx_getBlockByHashWithPivotAssumption✅ Supported
cfx_getBlockRewardInfo❌ Not supported yet
cfx_getBlocksByEpoch✅ Supported
cfx_getCode✅ Supported
cfx_getCollateralForStorage✅ Supported
cfx_getConfirmationRiskByHash✅ Supported
cfx_getInterestRate✅ Supported
cfx_getLogs✅ Supported
cfx_getNextNonce✅ Supported
cfx_getSkippedBlocksByEpoch✅ Supported
cfx_getSponsorInfo✅ Supported
cfx_getStakingBalance✅ Supported
cfx_getStatus✅ Supported
cfx_getStorageAt✅ Supported
cfx_getStorageRoot✅ Supported
cfx_getTransactionByHash✅ Supported
cfx_getTransactionReceipt✅ Supported
cfx_sendRawTransaction✅ Supported
cfx_getSupplyInfo❌ Not supported yet