Skip to content

Commit

Permalink
Problem: json-rpc failed on pruned nodes (backport crypto-org-chain#550)
Browse files Browse the repository at this point in the history
Solution:
- Make basic json-rpc apis works on pruned nodes
- Test with integration tests
  • Loading branch information
yihuang committed Jun 30, 2022
1 parent 75c2672 commit 79fac1b
Show file tree
Hide file tree
Showing 6 changed files with 194 additions and 28 deletions.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ replace (

github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1

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

google.golang.org/grpc => google.golang.org/grpc v1.33.2
)
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -271,8 +271,6 @@ github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsr
github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/crypto-org-chain/ethermint v0.10.0-alpha1-cronos-10 h1:QLICrljqG8eJ4X+JCqvWf1Lbg/TXS+lxoFbcezBpyjc=
github.com/crypto-org-chain/ethermint v0.10.0-alpha1-cronos-10/go.mod h1:T4f1p3L5kccbjBZMtJLKfOLiUXTO1OuS1I7FzQuJD+w=
github.com/crypto-org-chain/ibc-go/v2 v2.2.0-hooks2 h1:elj+Tb/3O9GA3pv62zkc1B0P8hl1WHmF6vF8PInEJm4=
github.com/crypto-org-chain/ibc-go/v2 v2.2.0-hooks2/go.mod h1:rAHRlBcRiHPP/JszN+08SJx3pegww9bcVncIb9QLx7I=
github.com/crypto-org-chain/keyring v1.1.6-fixes h1:AUFSu56NY6XobY6XfRoDx6v3loiOrHK5MNUm32GEjwA=
Expand Down Expand Up @@ -1166,6 +1164,8 @@ github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q
github.com/xlab/treeprint v0.0.0-20180616005107-d6fb6747feb6/go.mod h1:ce1O1j6UtZfjr22oyGxGLbauSBp2YVXpARAosm7dHBg=
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
github.com/ybbus/jsonrpc v2.1.2+incompatible/go.mod h1:XJrh1eMSzdIYFbM08flv0wp5G35eRniyeGut1z+LSiE=
github.com/yihuang/ethermint v0.10.0-cronos.0.20220630073727-4a4fd6003e12 h1:3FFxlzlEuOkyDMDFst8rBZOVgxpaqblnWuY9NG+nIT8=
github.com/yihuang/ethermint v0.10.0-cronos.0.20220630073727-4a4fd6003e12/go.mod h1:T4f1p3L5kccbjBZMtJLKfOLiUXTO1OuS1I7FzQuJD+w=
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
Expand Down
6 changes: 3 additions & 3 deletions gomod2nix.toml
Original file line number Diff line number Diff line change
Expand Up @@ -1434,9 +1434,9 @@ schema = 1
version = "v0.6.7"
hash = "sha256-hl/3RrBrpkk2zA6dmrNlIYKs1/GfqegSscDSkA5Pjlo="
[mod."github.com/tharsis/ethermint"]
version = "v0.10.0-alpha1-cronos-10"
hash = "sha256-EfYOvGreGToosDcqg1MBCHwSRSFdBIVvMlXIlYFFH0A="
replaced = "github.com/crypto-org-chain/ethermint"
version = "v0.10.0-cronos.0.20220630073727-4a4fd6003e12"
hash = "sha256-23OXZLkqPiwgpa3BcRan/MC7I6hsVm91VWuawOynpu0="
replaced = "github.com/yihuang/ethermint"
[mod."github.com/tidwall/gjson"]
version = "v1.6.7"
hash = "sha256-GL6MI9oNq+Pjxai9RtDPBeSpIuMTPQZPsB2vcntCBr8="
Expand Down
64 changes: 64 additions & 0 deletions integration_tests/configs/pruned-node.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
dotenv: ../../scripts/.env
cronos_777-1:
cmd: cronosd
start-flags: "--trace"
app-config:
minimum-gas-prices: 0basetcro
index-events:
- ethereum_tx.ethereumTxHash
pruning: "everything"
state-sync:
snapshot-interval: 0
json-rpc:
address: "0.0.0.0:{EVMRPC_PORT}"
ws-address: "0.0.0.0:{EVMRPC_PORT_WS}"
api: "eth,net,web3,debug,cronos"
validators:
- coins: 1000000000000000000stake,10000000000000000000000basetcro
staked: 1000000000000000000stake
mnemonic: ${VALIDATOR1_MNEMONIC}
- coins: 1000000000000000000stake,10000000000000000000000basetcro
staked: 1000000000000000000stake
mnemonic: ${VALIDATOR2_MNEMONIC}
accounts:
- name: community
coins: 10000000000000000000000basetcro
mnemonic: ${COMMUNITY_MNEMONIC}
- name: signer1
coins: 20000000000000000000000basetcro
mnemonic: ${SIGNER1_MNEMONIC}
- name: signer2
coins: 30000000000000000000000basetcro
mnemonic: ${SIGNER2_MNEMONIC}


genesis:
consensus_params:
block:
max_bytes: "1048576"
max_gas: "81500000"
app_state:
evm:
params:
evm_denom: basetcro
cronos:
params:
cronos_admin: ${CRONOS_ADMIN}
enable_auto_deployment: true
ibc_cro_denom: ${IBC_CRO_DENOM}
gov:
voting_params:
voting_period: "10s"
deposit_params:
max_deposit_period: "10s"
min_deposit:
- denom: "basetcro"
amount: "1"
transfer:
params:
receive_enabled: true
send_enabled: true
feemarket:
params:
no_base_fee: false
base_fee: "100000000000"
108 changes: 108 additions & 0 deletions integration_tests/test_pruned_node.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
from pathlib import Path

import pytest
from eth_bloom import BloomFilter
from eth_utils import abi, big_endian_to_int
from hexbytes import HexBytes
from web3.datastructures import AttributeDict

from .network import setup_custom_cronos
from .utils import (
ADDRS,
CONTRACTS,
KEYS,
deploy_contract,
sign_transaction,
wait_for_new_blocks,
)


@pytest.fixture(scope="module")
def cronos(request, tmp_path_factory):
"""start-cronos
params: enable_auto_deployment
"""
yield from setup_custom_cronos(
tmp_path_factory.mktemp("pruned"),
26900,
Path(__file__).parent / "configs/pruned-node.yaml",
)


def test_pruned_node(cronos):
"""
test basic json-rpc apis works in pruned node
"""
w3 = cronos.w3
erc20 = deploy_contract(
w3,
CONTRACTS["TestERC20A"],
key=KEYS["validator"],
)
tx = erc20.functions.transfer(ADDRS["community"], 10).buildTransaction(
{"from": ADDRS["validator"]}
)
signed = sign_transaction(w3, tx, KEYS["validator"])
txhash = w3.eth.send_raw_transaction(signed.rawTransaction)

print("wait for prunning happens")
wait_for_new_blocks(cronos.cosmos_cli(0), 10)

txreceipt = w3.eth.wait_for_transaction_receipt(txhash)
assert len(txreceipt.logs) == 1
expect_log = {
"address": erc20.address,
"topics": [
HexBytes(
abi.event_signature_to_log_topic("Transfer(address,address,uint256)")
),
HexBytes(b"\x00" * 12 + HexBytes(ADDRS["validator"])),
HexBytes(b"\x00" * 12 + HexBytes(ADDRS["community"])),
],
"data": "0x000000000000000000000000000000000000000000000000000000000000000a",
"transactionIndex": 0,
"logIndex": 0,
"removed": False,
}
assert expect_log.items() <= txreceipt.logs[0].items()

# check block bloom
block = w3.eth.get_block(txreceipt.blockNumber)
assert "baseFeePerGas" in block
assert block.miner == "0x0000000000000000000000000000000000000000"
bloom = BloomFilter(big_endian_to_int(block.logsBloom))
assert HexBytes(erc20.address) in bloom
for topic in expect_log["topics"]:
assert topic in bloom

tx1 = w3.eth.get_transaction(txhash)
tx2 = w3.eth.get_transaction_by_block(
txreceipt.blockNumber, txreceipt.transactionIndex
)
exp_tx = AttributeDict(
{
"from": "0x57f96e6B86CdeFdB3d412547816a82E3E0EbF9D2",
"gas": 51503,
"input": (
"0xa9059cbb000000000000000000000000378c50d9264c63f3f92b806d4ee56e"
"9d86ffb3ec000000000000000000000000000000000000000000000000000000"
"000000000a"
),
"nonce": 2,
"to": erc20.address,
"transactionIndex": 0,
"value": 0,
"type": "0x2",
"accessList": [],
"chainId": "0x309",
}
)
assert tx1 == tx2
for name in exp_tx.keys():
assert tx1[name] == tx2[name] == exp_tx[name]

print(
w3.eth.get_logs(
{"fromBlock": txreceipt.blockNumber, "toBlock": txreceipt.blockNumber}
)
)
38 changes: 16 additions & 22 deletions x/cronos/rpc/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,23 +93,19 @@ func (api *CronosAPI) getBlockDetail(blockNrOrHash rpctypes.BlockNumberOrHash) (
err error,
) {
var blockNum rpctypes.BlockNumber
blockNum, err = api.getBlockNumber(blockNrOrHash)
resBlock, err = api.getBlock(blockNrOrHash)
if err != nil {
return
}
resBlock, err = api.clientCtx.Client.Block(api.ctx, blockNum.TmHeight())
if err != nil {
api.logger.Debug("block not found", "height", blockNum, "error", err.Error())
api.logger.Debug("block not found", "height", blockNrOrHash, "error", err.Error())
return
}
blockNumber = resBlock.Block.Height
blockHash = common.BytesToHash(resBlock.Block.Header.Hash()).Hex()
blockRes, err = api.clientCtx.Client.BlockResults(api.ctx, &blockNumber)
blockRes, err = api.backend.GetTendermintBlockResultByNumber(&blockNumber)
if err != nil {
api.logger.Debug("failed to retrieve block results", "height", blockNum, "error", err.Error())
return
}
baseFee, err = api.backend.BaseFee(blockNumber)
baseFee, err = api.backend.BaseFee(blockRes)
if err != nil {
return
}
Expand Down Expand Up @@ -390,20 +386,18 @@ func (api *CronosAPI) ReplayBlock(blockNrOrHash rpctypes.BlockNumberOrHash, post
return receipts, nil
}

// getBlockNumber returns the BlockNumber from BlockNumberOrHash
func (api *CronosAPI) getBlockNumber(blockNrOrHash rpctypes.BlockNumberOrHash) (rpctypes.BlockNumber, error) {
switch {
case blockNrOrHash.BlockHash == nil && blockNrOrHash.BlockNumber == nil:
return rpctypes.EthEarliestBlockNumber, fmt.Errorf("types BlockHash and BlockNumber cannot be both nil")
case blockNrOrHash.BlockHash != nil:
blockHeader, err := api.backend.HeaderByHash(*blockNrOrHash.BlockHash)
if err != nil {
return rpctypes.EthEarliestBlockNumber, err
// getBlock returns the BlockNumber from BlockNumberOrHash
func (api *CronosAPI) getBlock(blockNrOrHash rpctypes.BlockNumberOrHash) (blk *coretypes.ResultBlock, err error) {
if blockNrOrHash.BlockHash != nil {
blk, err = api.backend.GetTendermintBlockByHash(*blockNrOrHash.BlockHash)
} else {
var blockNumber rpctypes.BlockNumber
if blockNrOrHash.BlockNumber != nil {
blockNumber = *blockNrOrHash.BlockNumber
} else if blockNrOrHash.BlockHash == nil && blockNrOrHash.BlockNumber == nil {
return nil, fmt.Errorf("types BlockHash and BlockNumber cannot be both nil")
}
return rpctypes.NewBlockNumber(blockHeader.Number), nil
case blockNrOrHash.BlockNumber != nil:
return *blockNrOrHash.BlockNumber, nil
default:
return rpctypes.EthEarliestBlockNumber, nil
blk, err = api.backend.GetTendermintBlockByNumber(blockNumber)
}
return
}

0 comments on commit 79fac1b

Please sign in to comment.