Skip to content

Commit 0c23f9e

Browse files
author
yihuang
authored
Problem: json-rpc failed on pruned nodes (backport #550) (#567)
* Problem: json-rpc failed on pruned nodes (backport #550) Solution: - Make basic json-rpc apis works on pruned nodes - Test with integration tests fix test config * Update x/cronos/rpc/api.go * use tags/ldflags directly
1 parent 0d15321 commit 0c23f9e

7 files changed

Lines changed: 207 additions & 39 deletions

File tree

default.nix

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,13 @@
1010
let
1111
version = "v0.7.0";
1212
pname = "cronosd";
13-
tags = lib.concatStringsSep "," (
14-
[ "ledger" "netgo" network ]
15-
++ lib.lists.optionals (db_backend == "rocksdb") [ "rocksdb" ]
16-
);
13+
tags = [ "ledger" "netgo" network ]
14+
++ lib.lists.optional (db_backend == "rocksdb") "rocksdb";
1715
ldflags = lib.concatStringsSep "\n" ([
1816
"-X github.com/cosmos/cosmos-sdk/version.Name=cronos"
1917
"-X github.com/cosmos/cosmos-sdk/version.AppName=${pname}"
2018
"-X github.com/cosmos/cosmos-sdk/version.Version=${version}"
21-
"-X github.com/cosmos/cosmos-sdk/version.BuildTags=${tags}"
19+
"-X github.com/cosmos/cosmos-sdk/version.BuildTags=${lib.concatStringsSep "," tags}"
2220
"-X github.com/cosmos/cosmos-sdk/version.Commit=${rev}"
2321
] ++ lib.lists.optionals (db_backend == "rocksdb") [
2422
"-X github.com/cosmos/cosmos-sdk/types.DBBackend=rocksdb"
@@ -28,7 +26,7 @@ let
2826
];
2927
in
3028
buildGoApplication rec {
31-
inherit pname version buildInputs;
29+
inherit pname version buildInputs tags ldflags;
3230
src = (nix-gitignore.gitignoreSourcePure [
3331
"/*" # ignore all, then add whitelists
3432
"!/x/"
@@ -44,11 +42,6 @@ buildGoApplication rec {
4442
pwd = src; # needed to support replace
4543
subPackages = [ "cmd/cronosd" ];
4644
CGO_ENABLED = "1";
47-
buildFlags = "-tags=${tags}";
48-
buildFlagsArray = ''
49-
-ldflags=
50-
${ldflags}
51-
'';
5245

5346
meta = with lib; {
5447
description = "Official implementation of the Cronos blockchain protocol";

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ replace (
164164

165165
github.com/tendermint/tendermint => github.com/tendermint/tendermint v0.34.20-rc0.0.20220630153554-17f4ea3680de
166166

167-
github.com/tharsis/ethermint => github.com/crypto-org-chain/ethermint v0.10.0-alpha1-cronos-10
167+
github.com/tharsis/ethermint => github.com/crypto-org-chain/ethermint v0.10.0-cronos.0.20220630073727-4a4fd6003e12
168168

169169
google.golang.org/grpc => google.golang.org/grpc v1.33.2
170170
)

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -308,8 +308,8 @@ github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46t
308308
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
309309
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
310310
github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
311-
github.com/crypto-org-chain/ethermint v0.10.0-alpha1-cronos-10 h1:QLICrljqG8eJ4X+JCqvWf1Lbg/TXS+lxoFbcezBpyjc=
312-
github.com/crypto-org-chain/ethermint v0.10.0-alpha1-cronos-10/go.mod h1:T4f1p3L5kccbjBZMtJLKfOLiUXTO1OuS1I7FzQuJD+w=
311+
github.com/crypto-org-chain/ethermint v0.10.0-cronos.0.20220630073727-4a4fd6003e12 h1:kAfE/HZ9DNDXjEi9fGI8bkZDwSNBJp17tGj3CWKWDCM=
312+
github.com/crypto-org-chain/ethermint v0.10.0-cronos.0.20220630073727-4a4fd6003e12/go.mod h1:T4f1p3L5kccbjBZMtJLKfOLiUXTO1OuS1I7FzQuJD+w=
313313
github.com/crypto-org-chain/ibc-go/v2 v2.2.0-hooks2 h1:elj+Tb/3O9GA3pv62zkc1B0P8hl1WHmF6vF8PInEJm4=
314314
github.com/crypto-org-chain/ibc-go/v2 v2.2.0-hooks2/go.mod h1:rAHRlBcRiHPP/JszN+08SJx3pegww9bcVncIb9QLx7I=
315315
github.com/crypto-org-chain/keyring v1.1.6-fixes h1:AUFSu56NY6XobY6XfRoDx6v3loiOrHK5MNUm32GEjwA=

gomod2nix.toml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
schema = 1
1+
schema = 3
22

33
[mod]
44
[mod."4d63.com/gochecknoglobals"]
@@ -1865,6 +1865,7 @@ schema = 1
18651865
[mod."github.com/tendermint/tendermint"]
18661866
version = "v0.34.20-rc0.0.20220630153554-17f4ea3680de"
18671867
hash = "sha256-19B4E/sR9wX1jistbJUPo9H78jgQKT9ikkivTGT7Ce4="
1868+
replaced = "github.com/tendermint/tendermint"
18681869
[mod."github.com/tendermint/tm-db"]
18691870
version = "v0.6.7"
18701871
hash = "sha256-hl/3RrBrpkk2zA6dmrNlIYKs1/GfqegSscDSkA5Pjlo="
@@ -1878,8 +1879,8 @@ schema = 1
18781879
version = "v1.4.11"
18791880
hash = "sha256-WLzChh6OfePXm6rv+jNHCS0IA57z3hEKcaCKg84LILY="
18801881
[mod."github.com/tharsis/ethermint"]
1881-
version = "v0.10.0-alpha1-cronos-10"
1882-
hash = "sha256-EfYOvGreGToosDcqg1MBCHwSRSFdBIVvMlXIlYFFH0A="
1882+
version = "v0.10.0-cronos.0.20220630073727-4a4fd6003e12"
1883+
hash = "sha256-23OXZLkqPiwgpa3BcRan/MC7I6hsVm91VWuawOynpu0="
18831884
replaced = "github.com/crypto-org-chain/ethermint"
18841885
[mod."github.com/tidwall/gjson"]
18851886
version = "v1.6.7"
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
dotenv: ../../scripts/.env
2+
cronos_777-1:
3+
cmd: cronosd
4+
start-flags: "--trace"
5+
app-config:
6+
minimum-gas-prices: 0basetcro
7+
index-events:
8+
- ethereum_tx.ethereumTxHash
9+
pruning: "everything"
10+
state-sync:
11+
snapshot-interval: 0
12+
json-rpc:
13+
address: "0.0.0.0:{EVMRPC_PORT}"
14+
ws-address: "0.0.0.0:{EVMRPC_PORT_WS}"
15+
api: "eth,net,web3,debug,cronos"
16+
validators:
17+
- coins: 1000000000000000000stake,10000000000000000000000basetcro
18+
staked: 1000000000000000000stake
19+
mnemonic: ${VALIDATOR1_MNEMONIC}
20+
- coins: 1000000000000000000stake,10000000000000000000000basetcro
21+
staked: 1000000000000000000stake
22+
mnemonic: ${VALIDATOR2_MNEMONIC}
23+
accounts:
24+
- name: community
25+
coins: 10000000000000000000000basetcro
26+
mnemonic: ${COMMUNITY_MNEMONIC}
27+
- name: signer1
28+
coins: 20000000000000000000000basetcro
29+
mnemonic: ${SIGNER1_MNEMONIC}
30+
- name: signer2
31+
coins: 30000000000000000000000basetcro
32+
mnemonic: ${SIGNER2_MNEMONIC}
33+
34+
35+
genesis:
36+
consensus_params:
37+
block:
38+
max_bytes: "1048576"
39+
max_gas: "81500000"
40+
app_state:
41+
evm:
42+
params:
43+
evm_denom: basetcro
44+
cronos:
45+
params:
46+
cronos_admin: ${CRONOS_ADMIN}
47+
enable_auto_deployment: true
48+
ibc_cro_denom: ${IBC_CRO_DENOM}
49+
gov:
50+
voting_params:
51+
voting_period: "10s"
52+
deposit_params:
53+
max_deposit_period: "10s"
54+
min_deposit:
55+
- denom: "basetcro"
56+
amount: "1"
57+
transfer:
58+
params:
59+
receive_enabled: true
60+
send_enabled: true
61+
feemarket:
62+
params:
63+
no_base_fee: false
64+
initial_base_fee: "100000000000"
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
from pathlib import Path
2+
3+
import pytest
4+
from eth_bloom import BloomFilter
5+
from eth_utils import abi, big_endian_to_int
6+
from hexbytes import HexBytes
7+
from web3.datastructures import AttributeDict
8+
9+
from .network import setup_custom_cronos
10+
from .utils import (
11+
ADDRS,
12+
CONTRACTS,
13+
KEYS,
14+
deploy_contract,
15+
sign_transaction,
16+
wait_for_new_blocks,
17+
)
18+
19+
20+
@pytest.fixture(scope="module")
21+
def cronos(request, tmp_path_factory):
22+
"""start-cronos
23+
params: enable_auto_deployment
24+
"""
25+
yield from setup_custom_cronos(
26+
tmp_path_factory.mktemp("pruned"),
27+
26900,
28+
Path(__file__).parent / "configs/pruned-node.yaml",
29+
)
30+
31+
32+
def test_pruned_node(cronos):
33+
"""
34+
test basic json-rpc apis works in pruned node
35+
"""
36+
w3 = cronos.w3
37+
erc20 = deploy_contract(
38+
w3,
39+
CONTRACTS["TestERC20A"],
40+
key=KEYS["validator"],
41+
)
42+
tx = erc20.functions.transfer(ADDRS["community"], 10).buildTransaction(
43+
{"from": ADDRS["validator"]}
44+
)
45+
signed = sign_transaction(w3, tx, KEYS["validator"])
46+
txhash = w3.eth.send_raw_transaction(signed.rawTransaction)
47+
48+
print("wait for prunning happens")
49+
wait_for_new_blocks(cronos.cosmos_cli(0), 10)
50+
51+
txreceipt = w3.eth.wait_for_transaction_receipt(txhash)
52+
assert len(txreceipt.logs) == 1
53+
expect_log = {
54+
"address": erc20.address,
55+
"topics": [
56+
HexBytes(
57+
abi.event_signature_to_log_topic("Transfer(address,address,uint256)")
58+
),
59+
HexBytes(b"\x00" * 12 + HexBytes(ADDRS["validator"])),
60+
HexBytes(b"\x00" * 12 + HexBytes(ADDRS["community"])),
61+
],
62+
"data": "0x000000000000000000000000000000000000000000000000000000000000000a",
63+
"transactionIndex": 0,
64+
"logIndex": 0,
65+
"removed": False,
66+
}
67+
assert expect_log.items() <= txreceipt.logs[0].items()
68+
69+
# check get_balance and eth_call don't work on pruned state
70+
with pytest.raises(Exception):
71+
w3.eth.get_balance(ADDRS["validator"], block_identifier=txreceipt.blockNumber)
72+
with pytest.raises(Exception):
73+
erc20.caller(block_identifier=txreceipt.blockNumber).balanceOf(
74+
ADDRS["validator"]
75+
)
76+
77+
# check block bloom
78+
block = w3.eth.get_block(txreceipt.blockNumber)
79+
assert "baseFeePerGas" in block
80+
assert block.miner == "0x0000000000000000000000000000000000000000"
81+
bloom = BloomFilter(big_endian_to_int(block.logsBloom))
82+
assert HexBytes(erc20.address) in bloom
83+
for topic in expect_log["topics"]:
84+
assert topic in bloom
85+
86+
tx1 = w3.eth.get_transaction(txhash)
87+
tx2 = w3.eth.get_transaction_by_block(
88+
txreceipt.blockNumber, txreceipt.transactionIndex
89+
)
90+
exp_tx = AttributeDict(
91+
{
92+
"from": "0x57f96e6B86CdeFdB3d412547816a82E3E0EbF9D2",
93+
"gas": 51503,
94+
"input": (
95+
"0xa9059cbb000000000000000000000000378c50d9264c63f3f92b806d4ee56e"
96+
"9d86ffb3ec000000000000000000000000000000000000000000000000000000"
97+
"000000000a"
98+
),
99+
"nonce": 2,
100+
"to": erc20.address,
101+
"transactionIndex": 0,
102+
"value": 0,
103+
"type": "0x2",
104+
"accessList": [],
105+
"chainId": "0x309",
106+
}
107+
)
108+
assert tx1 == tx2
109+
for name in exp_tx.keys():
110+
assert tx1[name] == tx2[name] == exp_tx[name]
111+
112+
print(
113+
w3.eth.get_logs(
114+
{"fromBlock": txreceipt.blockNumber, "toBlock": txreceipt.blockNumber}
115+
)
116+
)

x/cronos/rpc/api.go

Lines changed: 16 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -93,23 +93,19 @@ func (api *CronosAPI) getBlockDetail(blockNrOrHash rpctypes.BlockNumberOrHash) (
9393
err error,
9494
) {
9595
var blockNum rpctypes.BlockNumber
96-
blockNum, err = api.getBlockNumber(blockNrOrHash)
96+
resBlock, err = api.getBlock(blockNrOrHash)
9797
if err != nil {
98-
return
99-
}
100-
resBlock, err = api.clientCtx.Client.Block(api.ctx, blockNum.TmHeight())
101-
if err != nil {
102-
api.logger.Debug("block not found", "height", blockNum, "error", err.Error())
98+
api.logger.Debug("block not found", "height", blockNrOrHash, "error", err.Error())
10399
return
104100
}
105101
blockNumber = resBlock.Block.Height
106102
blockHash = common.BytesToHash(resBlock.Block.Header.Hash()).Hex()
107-
blockRes, err = api.clientCtx.Client.BlockResults(api.ctx, &blockNumber)
103+
blockRes, err = api.backend.GetTendermintBlockResultByNumber(&blockNumber)
108104
if err != nil {
109105
api.logger.Debug("failed to retrieve block results", "height", blockNum, "error", err.Error())
110106
return
111107
}
112-
baseFee, err = api.backend.BaseFee(blockNumber)
108+
baseFee, err = api.backend.BaseFee(blockRes)
113109
if err != nil {
114110
return
115111
}
@@ -390,20 +386,18 @@ func (api *CronosAPI) ReplayBlock(blockNrOrHash rpctypes.BlockNumberOrHash, post
390386
return receipts, nil
391387
}
392388

393-
// getBlockNumber returns the BlockNumber from BlockNumberOrHash
394-
func (api *CronosAPI) getBlockNumber(blockNrOrHash rpctypes.BlockNumberOrHash) (rpctypes.BlockNumber, error) {
395-
switch {
396-
case blockNrOrHash.BlockHash == nil && blockNrOrHash.BlockNumber == nil:
397-
return rpctypes.EthEarliestBlockNumber, fmt.Errorf("types BlockHash and BlockNumber cannot be both nil")
398-
case blockNrOrHash.BlockHash != nil:
399-
blockHeader, err := api.backend.HeaderByHash(*blockNrOrHash.BlockHash)
400-
if err != nil {
401-
return rpctypes.EthEarliestBlockNumber, err
389+
// getBlock returns the block from BlockNumberOrHash
390+
func (api *CronosAPI) getBlock(blockNrOrHash rpctypes.BlockNumberOrHash) (blk *coretypes.ResultBlock, err error) {
391+
if blockNrOrHash.BlockHash != nil {
392+
blk, err = api.backend.GetTendermintBlockByHash(*blockNrOrHash.BlockHash)
393+
} else {
394+
var blockNumber rpctypes.BlockNumber
395+
if blockNrOrHash.BlockNumber != nil {
396+
blockNumber = *blockNrOrHash.BlockNumber
397+
} else if blockNrOrHash.BlockHash == nil && blockNrOrHash.BlockNumber == nil {
398+
return nil, fmt.Errorf("types BlockHash and BlockNumber cannot be both nil")
402399
}
403-
return rpctypes.NewBlockNumber(blockHeader.Number), nil
404-
case blockNrOrHash.BlockNumber != nil:
405-
return *blockNrOrHash.BlockNumber, nil
406-
default:
407-
return rpctypes.EthEarliestBlockNumber, nil
400+
blk, err = api.backend.GetTendermintBlockByNumber(blockNumber)
408401
}
402+
return
409403
}

0 commit comments

Comments
 (0)