Skip to content

Add external calls within consensus mechanism #88

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

Open
wants to merge 149 commits into
base: tm_w3q
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 132 commits
Commits
Show all changes
149 commits
Select commit Hold shift + click to select a range
2d1fd4f
add test
cyl19970726 Apr 20, 2022
41b78e0
Merge branch 'tm_w3q' of https://github.com/QuarkChain/go-ethereum in…
cyl19970726 Apr 24, 2022
8035296
Merge branch 'tm_w3q' of https://github.com/QuarkChain/go-ethereum in…
cyl19970726 Apr 29, 2022
c493347
update RPCMarshalHeader
ping-ke May 7, 2022
61ac7a0
add relayer
ping-ke May 7, 2022
51c5bc5
fix bug
ping-ke May 10, 2022
98dca72
Merge branch 'tm_w3q_relayer' of https://github.com/QuarkChain/go-eth…
cyl19970726 May 10, 2022
9fa8e54
Merge branch 'tm_w3q_rpc' of https://github.com/QuarkChain/go-ethereu…
cyl19970726 May 10, 2022
31b2f3e
Merge branch 'tm_w3q' of https://github.com/QuarkChain/go-ethereum in…
cyl19970726 May 17, 2022
08f78fa
Add externalCallResult property inside transaction
cyl19970726 May 19, 2022
ee78ffa
add test for externalCallResult in transaction
cyl19970726 May 19, 2022
1070a67
transaction_test.go : Fix some bugs in the old version of the test
cyl19970726 May 19, 2022
0b00135
add a precompile contract names crossChainCall
cyl19970726 May 19, 2022
3afbc06
add externalClient and verify that externalCallResult is after transa…
cyl19970726 May 19, 2022
77d28bd
fix external call result bug
cyl19970726 May 20, 2022
204e451
add test for externalcall
cyl19970726 May 20, 2022
76b2e7f
encode crossChainCall rescult thorugh rlp
cyl19970726 May 21, 2022
4d1b4d7
update state_test
cyl19970726 May 21, 2022
1c9a469
add external call config in ChainConfig
cyl19970726 May 21, 2022
cd3dbcc
Add ExternalCallClient() to consensus.engine interface
cyl19970726 May 21, 2022
04bd4f1
support external call for normal node
cyl19970726 May 22, 2022
f73768e
update state_test.go
cyl19970726 May 23, 2022
183a9a2
add test for external call in evm
cyl19970726 May 23, 2022
3140cbe
add more test
cyl19970726 May 23, 2022
d916318
remove unused files
cyl19970726 May 24, 2022
8a9eb7d
Change the address of a crosss_chain_call precompiled contract from 0…
cyl19970726 May 27, 2022
a5f698c
check logIdx to avoid exceeding the bounds of the log array
cyl19970726 May 27, 2022
9195ea1
deal with chainId and return err if tracePtr exceeds the bound
cyl19970726 May 27, 2022
06e72a8
use abiPack method to encode the result of cross chain call
cyl19970726 May 27, 2022
17ae548
externalCall.version string=>uint64
cyl19970726 May 27, 2022
b3db020
add supportChainID check
cyl19970726 May 27, 2022
f81ba58
Set the environment for executing external calls
cyl19970726 Jun 1, 2022
89b8fc4
update external config
cyl19970726 Jun 1, 2022
553cd9c
Split error into expect error and unexpect error
cyl19970726 Jun 1, 2022
29a9b02
fix external call test
cyl19970726 Jun 2, 2022
c923ff9
update external call test
cyl19970726 Jun 2, 2022
7b481ce
Add a way to handle unexpected errors
cyl19970726 Jun 2, 2022
116b5f8
optimize crosschaincall
cyl19970726 Jun 5, 2022
11015f3
optimize test
cyl19970726 Jun 5, 2022
4be6da3
optimize cross chain call
cyl19970726 Jun 8, 2022
db86510
update core/state_processor_test.go
cyl19970726 Jun 8, 2022
32b2200
add ExternalCallResult field in receipt
cyl19970726 Jun 9, 2022
67fb03d
add receipt storage test under condition that receipt.ExternalCallRes…
cyl19970726 Jun 9, 2022
a341301
update execution of miner deal cross_chain_call_result
cyl19970726 Jun 9, 2022
98d2608
add perByteGasPrice to calculate the gas_used of cross chain call result
cyl19970726 Jun 9, 2022
5475f0e
modify chain_maker.go
cyl19970726 Jun 9, 2022
0ad8eaa
add external_call_result at transaction and receipt while rpc call
cyl19970726 Jun 9, 2022
352b528
update transactions
cyl19970726 Jun 9, 2022
56e3188
update state_process.go to support receipt.externalCallResult
cyl19970726 Jun 9, 2022
1e3d65f
update params/config.go
cyl19970726 Jun 9, 2022
83896e6
fix tendermint return bug
cyl19970726 Jun 9, 2022
1849404
update genesis.go DefaultWeb3QTestnetGenesisBlock
cyl19970726 Jun 9, 2022
553f0af
update core/genesis.go
cyl19970726 Jun 9, 2022
53bcc5a
core/vm/contracts.go CallResult => GetLogByTxHash
cyl19970726 Jun 9, 2022
fbdb9c1
core/vm/contracts.go tracePtr => traceIdx
cyl19970726 Jun 9, 2022
a0cab3b
add unexpect err as ErrUnsupportMethod
cyl19970726 Jun 9, 2022
733de42
opmitize contracts.go
cyl19970726 Jun 9, 2022
b070b54
update evm.reset to include in.crossChainTraces and in.traceIdx
cyl19970726 Jun 9, 2022
6582d32
update DoCall() to support external call
cyl19970726 Jun 9, 2022
2b0e019
tx.externalCallResult() is not included when calculating tx.Hash()
cyl19970726 Jun 12, 2022
7d7f293
miner setCrossChainResult at Tx
cyl19970726 Jun 12, 2022
76cd045
update internal/ethapi/api.go to support externalCallResult when call…
cyl19970726 Jun 12, 2022
8c6a272
verify crossChainCallResult when state syncing
cyl19970726 Jun 12, 2022
b5ad15c
update state_processor.go
cyl19970726 Jun 12, 2022
b4c0663
add test for tx.WithExternalCallResult()
cyl19970726 Jun 13, 2022
2dcea9e
add external flags
cyl19970726 Jun 15, 2022
8c62abb
update ethconfig with externalCall to merge chainconfig
cyl19970726 Jun 15, 2022
5ad4812
add external config at ethconfig
cyl19970726 Jun 15, 2022
3414b01
update worker submit tx process
cyl19970726 Jun 15, 2022
845d0c0
update flags
cyl19970726 Jun 15, 2022
cd2aa7a
update chain_maker to support externalCall
cyl19970726 Jun 15, 2022
e555de0
update chainConfig.ExternalCall.VerifyExternalCallResultWhenSyncState…
cyl19970726 Jun 15, 2022
f1996a6
update chainconfig
cyl19970726 Jun 15, 2022
80b8bae
update ethconfig
cyl19970726 Jun 15, 2022
b360f62
update state sync with external call result
cyl19970726 Jun 15, 2022
c2e567a
update DoCall()
cyl19970726 Jun 15, 2022
68e7778
Update the logic of worker processing externalCallResult
cyl19970726 Jun 15, 2022
3d52488
add new flags
cyl19970726 Jun 15, 2022
5a3e262
fix bug when client is nil
cyl19970726 Jun 20, 2022
85fd02a
add pre config
cyl19970726 Jun 20, 2022
bdff847
add Bench Test to externalCall
cyl19970726 Jun 21, 2022
71570e4
modify state_test
cyl19970726 Jun 21, 2022
76a638c
Merge branch 'tm_w3q' of https://github.com/QuarkChain/go-ethereum in…
cyl19970726 Jun 21, 2022
f2eb4b4
merge from tm_w3q
cyl19970726 Jun 21, 2022
7f4eaf8
web3QRinkeby network
cyl19970726 Jun 21, 2022
ad26459
add gasCost param to externalCall
cyl19970726 Jun 21, 2022
bf24cde
add web3Qrinkeby testnet
cyl19970726 Jun 21, 2022
5ba5530
remove unused file
cyl19970726 Jun 21, 2022
0d3f386
fix web3qRinkeby genesis bug
cyl19970726 Jun 22, 2022
f101f9a
add appendCrossChainCallTrace()
cyl19970726 Jun 23, 2022
1e1522f
modify external config
cyl19970726 Jun 27, 2022
6ff2538
modify ExternalCall.Role flag type
cyl19970726 Jun 27, 2022
8c097ab
fix issue of magic number of role and initialize client multiple times
cyl19970726 Jun 27, 2022
5dd02df
update intialize external call client in evm of chain_maker.go
cyl19970726 Jun 27, 2022
c4904cb
remove ExternalClient() in consensus
cyl19970726 Jun 27, 2022
7dc64a0
Revert "remove ExternalClient() in consensus"
cyl19970726 Jun 27, 2022
5040f68
initialize the externalCallClient when initializing the blockchain in…
cyl19970726 Jun 27, 2022
ae22739
remove the instance of externalCallClient from the ChainConfig.Extern…
cyl19970726 Jun 27, 2022
29145fe
Update the initialization of externalCallClient before entering the EVM
cyl19970726 Jun 27, 2022
aea3f9a
Update the initialization of externalCallClient before entering the E…
cyl19970726 Jun 27, 2022
b631444
fix the order of import packages
cyl19970726 Jun 27, 2022
3f706e2
fix the bug when initializing externalCallClient
cyl19970726 Jun 28, 2022
27e0e3c
update the processure of setting up vmConfig.externalCallClient when …
cyl19970726 Jun 28, 2022
0bee61a
update docall() to support externalcall
cyl19970726 Jun 29, 2022
3d61e40
refactor(eth/backend.go eth/ethconfig/config.go): a constant variabl…
cyl19970726 Jul 6, 2022
2578a8b
refactor(core/vm/contracts.go): sort precompile contracts by address
cyl19970726 Jul 6, 2022
08cec3b
refactor: remove extra comment
cyl19970726 Jul 6, 2022
0c054de
feat: verify the trie root hash of external_call_result when validate…
cyl19970726 Jul 7, 2022
86f63ad
refactor: remove extra code when external_call_client is nil for vali…
cyl19970726 Jul 7, 2022
3e8fe1e
fix(core): resolving disputes over ambiguous name `corssChainCallTrac…
cyl19970726 Jul 7, 2022
5b9faf1
Revert "feat: verify the trie root hash of external_call_result when …
cyl19970726 Jul 8, 2022
e1c6986
feat: move external_call_result into block.uncles
cyl19970726 Jul 9, 2022
d8cfa3f
feat(core/types): remove external call result from trnsaction
cyl19970726 Jul 9, 2022
039d0c4
Revert "add ExternalCallResult field in receipt"
cyl19970726 Jul 9, 2022
12b6660
Revert "add receipt storage test under condition that receipt.Externa…
cyl19970726 Jul 9, 2022
93984ae
fix: fixed a bug where the call result was stored in unlces when perf…
cyl19970726 Jul 11, 2022
ed0ffbf
refactor: remove verifyCallResInSync of chainConfig.ExternalCall
cyl19970726 Jul 13, 2022
ce7335f
feat: optimize process of external call by extra flag named EnableExt…
cyl19970726 Jul 13, 2022
92a3416
refactor: update chain_maker
cyl19970726 Jul 14, 2022
4d3d3aa
fix: fix bug when debug external call tx
cyl19970726 Jul 14, 2022
e90f49d
refactor: update worker process
cyl19970726 Jul 14, 2022
e4022d9
refactor(core/state_prefetcher.go): update
cyl19970726 Jul 14, 2022
9769f5e
refactor: update externalCall config at chainConfig
cyl19970726 Jul 14, 2022
d510e3c
refactor: update web3qTestNet config to support external call
cyl19970726 Jul 14, 2022
2939b60
build: remove web3qRinkeby net
cyl19970726 Jul 18, 2022
0d8e046
style: update format
cyl19970726 Jul 20, 2022
af7384c
refactor: fix issue
cyl19970726 Jul 20, 2022
058e43e
Revert "Add ExternalCallClient() to consensus.engine interface"
cyl19970726 Jul 25, 2022
926e606
refactor: expect error uses the same error handling method as unexpec…
cyl19970726 Jul 25, 2022
5f64330
fix: replace externalCallRole with ExternalCallEnableBlockNumber
cyl19970726 Jul 25, 2022
d8a21a8
refactor: remove extra testnet
cyl19970726 Jul 25, 2022
bea6e2f
feat: optimize state.Process() by setting the flag of whether to use …
cyl19970726 Jul 26, 2022
045416b
refactor: update launch process
cyl19970726 Jul 26, 2022
14a57d0
refactor: optimize the code of external call in the state synchroniza…
cyl19970726 Jul 26, 2022
74726dc
build: remove extra bootnode config
cyl19970726 Jul 26, 2022
15c5a6d
test: update external test
cyl19970726 Jul 27, 2022
114c261
fix: fix the bug of precompile contract(crossChainCall)
cyl19970726 Jul 27, 2022
6a0cb0f
refactor(internal/ethapi/api.go): add new rpc(eth_getExternalCallResult)
cyl19970726 Aug 3, 2022
124b5c0
refactor(ethclient/ethclient.go): update ethclient to support externa…
cyl19970726 Aug 3, 2022
47bc81f
test: add ethclient test
cyl19970726 Aug 3, 2022
b56f610
refactor: update state_process
cyl19970726 Aug 12, 2022
23de238
refactor: update log level when state_process()
cyl19970726 Aug 12, 2022
58da188
refactor: update miner log level
cyl19970726 Aug 12, 2022
4100ce9
refactor: update return error
cyl19970726 Aug 12, 2022
7584910
refactor: update gas calculate of externalCall
cyl19970726 Aug 12, 2022
9132377
feat: update the calculation formula of gas of externalCall
cyl19970726 Aug 12, 2022
99a3bf8
feat: update ExternalCallGas as 100000
cyl19970726 Aug 21, 2022
0ffe8a3
fix: fix the bootnodes conflict
cyl19970726 Sep 5, 2022
b27e201
refactor: remove unused comment
cyl19970726 Sep 15, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions cmd/geth/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,9 @@ var (
utils.ValContractFlag,
utils.ValChainIdFlag,
utils.ValChangeEpochIdFlag,
utils.ExternalCallRoleFlag,
utils.ExternalCallRpcFlag,
utils.ExternalCallSupportChainId,
utils.VMEnableDebugFlag,
utils.NetworkIdFlag,
utils.EthStatsURLFlag,
Expand Down
28 changes: 28 additions & 0 deletions cmd/utils/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,18 @@ var (
Name: "validator.rpc",
Usage: "rpc for Validator to update validator set",
}
ExternalCallEnableBlockNumber = cli.StringFlag{
Name: "externalcall.role",
Usage: "different role to support externalCall( \n role 0: disable external call \n role 1: node reuses client of consensus as external call client \n role 2: node without client of external call \n role 3: node with independent client of external call(callRpc is not empty))",
}
ExternalCallRpcFlag = cli.StringFlag{
Name: "externalcall.callrpc",
Usage: "rpc to launch independent external call client",
}
ExternalCallSupportChainId = cli.Uint64Flag{
Name: "externalcall.supportchainid",
Usage: "chainId of the target chain of the external call",
}
DeveloperFlag = cli.BoolFlag{
Name: "dev",
Usage: "Ephemeral proof-of-authority network with a pre-funded developer account, mining enabled",
Expand Down Expand Up @@ -1495,6 +1507,21 @@ func setTendermint(ctx *cli.Context, cfg *ethconfig.Config) {
}
}

func setExternalCall(ctx *cli.Context, cfg *ethconfig.Config) {
if ctx.GlobalIsSet(ExternalCallEnableBlockNumber.Name) {
cfg.ExternalCallEnableBlockNumber.SetString(ctx.GlobalString(ExternalCallEnableBlockNumber.Name), 10)
}

if ctx.GlobalIsSet(ExternalCallRpcFlag.Name) {
cfg.ExternalCallRpc = ctx.GlobalString(ExternalCallRpcFlag.Name)
}

if ctx.GlobalIsSet(ExternalCallSupportChainId.Name) {
cfg.ExternalCallSupportChainId = ctx.GlobalUint64(ExternalCallSupportChainId.Name)
}

}

func setMiner(ctx *cli.Context, cfg *miner.Config) {
if ctx.GlobalIsSet(MinerNotifyFlag.Name) {
cfg.Notify = strings.Split(ctx.GlobalString(MinerNotifyFlag.Name), ",")
Expand Down Expand Up @@ -1606,6 +1633,7 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) {
setTxPool(ctx, &cfg.TxPool)
setEthash(ctx, cfg)
setTendermint(ctx, cfg)
setExternalCall(ctx, cfg)
setMiner(ctx, &cfg.Miner)
setWhitelist(ctx, cfg)
setLes(ctx, cfg)
Expand Down
14 changes: 5 additions & 9 deletions consensus/tendermint/tendermint.go
Original file line number Diff line number Diff line change
Expand Up @@ -381,10 +381,6 @@ func (c *Tendermint) verifyHeader(chain consensus.ChainHeaderReader, header *typ
if header.MixDigest != (common.Hash{}) {
return errInvalidMixDigest
}
// Ensure that the block doesn't contain any uncles which are meaningless in PoA
if header.UncleHash != uncleHash {
return errInvalidUncleHash
}
// Ensure that the block's difficulty is meaningful (may not be correct at this point)
if header.Difficulty == nil || (header.Difficulty.Cmp(big.NewInt(1)) != 0) {
return errInvalidDifficulty
Expand Down Expand Up @@ -458,10 +454,10 @@ func (c *Tendermint) getEpochHeader(chain consensus.ChainHeaderReader, header *t
// VerifyUncles implements consensus.Engine, always returning an error for any
// uncles as this consensus mechanism doesn't permit uncles.
func (c *Tendermint) VerifyUncles(chain consensus.ChainReader, block *types.Block) error {
if len(block.Uncles()) > 0 {
return errors.New("uncles not allowed")
if len(block.Uncles()) <= len(block.Transactions()) {
return nil
}
return nil
return fmt.Errorf("the number of uncles exceeds the number of transactions")
}

// Prepare implements consensus.Engine, preparing all the consensus fields of the
Expand All @@ -482,7 +478,7 @@ func (c *Tendermint) Prepare(chain consensus.ChainHeaderReader, header *types.He
func (c *Tendermint) Finalize(chain consensus.ChainHeaderReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header) {
// No block rewards at the moment, so the state remains as is and uncles are dropped
header.Root = state.IntermediateRoot(chain.Config().IsEIP158(header.Number))
header.UncleHash = types.CalcUncleHash(nil)
header.UncleHash = types.CalcUncleHash(uncles)
}

// FinalizeAndAssemble implements consensus.Engine, ensuring no uncles are set,
Expand All @@ -492,7 +488,7 @@ func (c *Tendermint) FinalizeAndAssemble(chain consensus.ChainHeaderReader, head
c.Finalize(chain, header, state, txs, uncles)

// Assemble and return the final block for sealing
return types.NewBlock(header, txs, nil, receipts, trie.NewStackTrie(nil)), nil
return types.NewBlock(header, txs, uncles, receipts, trie.NewStackTrie(nil)), nil
}

// Seal implements consensus.Engine, attempting to create a sealed block using
Expand Down
1 change: 1 addition & 0 deletions core/block_validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ func (v *BlockValidator) ValidateBody(block *types.Block) error {
if err := v.engine.VerifyUncles(v.bc, block); err != nil {
return err
}
// The process of verifying uncleHash actually verifies all external call results in this block
if hash := types.CalcUncleHash(block.Uncles()); hash != header.UncleHash {
return fmt.Errorf("uncle root hash mismatch: have %x, want %x", hash, header.UncleHash)
}
Expand Down
4 changes: 2 additions & 2 deletions core/blockchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -1591,7 +1591,7 @@ func (bc *BlockChain) insertChain(chain types.Blocks, verifySeals, setHead bool)

// Process block using the parent state as reference point
substart := time.Now()
receipts, logs, usedGas, err := bc.processor.Process(block, statedb, bc.vmConfig)
receipts, logs, usedGas, err := bc.processor.Process(block, statedb, bc.vmConfig, false)
if err != nil {
bc.reportBlock(block, receipts, err)
atomic.StoreUint32(&followupInterrupt, 1)
Expand Down Expand Up @@ -2319,7 +2319,7 @@ func (bc *BlockChain) PreExecuteBlock(block *types.Block) (err error) {
err = fmt.Errorf("txHash mismatch, got %s, expect %s", block.TxHash(), txHash)
return
}
receipts, _, usedGas, err := bc.processor.Process(block, statedb, bc.vmConfig)
receipts, _, usedGas, err := bc.processor.Process(block, statedb, bc.vmConfig, true)
if err != nil {
return
}
Expand Down
2 changes: 1 addition & 1 deletion core/blockchain_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ func testBlockChainImport(chain types.Blocks, blockchain *BlockChain) error {
if err != nil {
return err
}
receipts, _, usedGas, err := blockchain.processor.Process(block, statedb, vm.Config{})
receipts, _, usedGas, err := blockchain.processor.Process(block, statedb, vm.Config{}, false)
if err != nil {
blockchain.reportBlock(block, receipts, err)
return err
Expand Down
30 changes: 26 additions & 4 deletions core/chain_makers.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,15 @@ package core

import (
"fmt"
"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/ethclient"
"math/big"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/consensus"
"github.com/ethereum/go-ethereum/consensus/misc"
"github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/params"
)
Expand All @@ -44,8 +45,9 @@ type BlockGen struct {
receipts []*types.Receipt
uncles []*types.Header

config *params.ChainConfig
engine consensus.Engine
config *params.ChainConfig
engine consensus.Engine
vmconfig *vm.Config
}

// SetCoinbase sets the coinbase of the generated block.
Expand Down Expand Up @@ -103,10 +105,20 @@ func (b *BlockGen) AddTxWithChain(bc *BlockChain, tx *types.Transaction) {
b.SetCoinbase(common.Address{})
}
b.statedb.Prepare(tx.Hash(), len(b.txs))
receipt, err := ApplyTransaction(b.config, bc, &b.header.Coinbase, b.gasPool, b.statedb, b.header, tx, &b.header.GasUsed, vm.Config{})

receipt, crossChainCallResult, err := ApplyTransaction(b.config, bc, &b.header.Coinbase, b.gasPool, b.statedb, b.header, tx, &b.header.GasUsed, *b.vmconfig)
if err != nil {
panic(err)
}

if len(crossChainCallResult) != 0 {
uncle := &types.Header{
Number: big.NewInt(int64(len(b.txs))),
TxHash: tx.Hash(),
Extra: crossChainCallResult,
}
b.uncles = append(b.uncles, uncle)
}
b.txs = append(b.txs, tx)
b.receipts = append(b.receipts, receipt)
}
Expand Down Expand Up @@ -225,6 +237,16 @@ func GenerateChain(config *params.ChainConfig, parent *types.Block, engine conse
chainreader := &fakeChainReader{config: config}
genblock := func(i int, parent *types.Block, statedb *state.StateDB) (*types.Block, types.Receipts) {
b := &BlockGen{i: i, chain: blocks, parent: parent, statedb: statedb, config: config, engine: engine}
if config.ExternalCall != nil {
// Here it is assumed that the node has an active rpc
client, err := ethclient.Dial(config.ExternalCall.CallRpc)
defer client.Close()
if err != nil {
return nil, nil
}
b.vmconfig = &vm.Config{ExternalCallClient: client}
}

b.header = makeHeader(chainreader, parent, statedb, b.engine)

// Set the difficulty for clique block. The chain maker doesn't have access
Expand Down
15 changes: 9 additions & 6 deletions core/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -438,15 +438,18 @@ func DefaultWeb3QTestnetGenesisBlock() *Genesis {
Timestamp: 1644537097,
Alloc: map[common.Address]GenesisAccount{
common.HexToAddress("0x0E961a6A6235eFDB9a0F0BC753E395211B77cc28"): {Balance: new(big.Int).Mul(big.NewInt(1000000000000000000), big.NewInt(1000000000))}, // 1e9 Ether
common.HexToAddress("0x5C935469C5592Aeeac3372e922d9bCEabDF8830d"): {Balance: new(big.Int).Mul(big.NewInt(1000000000000000000), big.NewInt(1000000000))}, // 1e9 Ether
common.HexToAddress("0x024d6050275eec53b233B467AdA12d2C65B3AEce"): {Balance: new(big.Int).Mul(big.NewInt(1000000000000000000), big.NewInt(1000000000))}, // 1e9 Ether
common.HexToAddress("0x96f22a48DcD4dFb99A11560b24bee02F374cA77D"): {Balance: new(big.Int).Mul(big.NewInt(1000000000000000000), big.NewInt(1000000000))}, // 1e9 Ether
common.HexToAddress("0x560CD6c5054847c2AFCAae0dd9E34E22E6f47100"): {Balance: new(big.Int).Mul(big.NewInt(1000000000000000000), big.NewInt(1000000000))}, // 1e9 Ether
common.HexToAddress("0x3d2Bf29BaB6ec95422Eb143e856df3B0E775e50c"): {Balance: new(big.Int).Mul(big.NewInt(1000000000000000000), big.NewInt(1000000000))}, // 1e9 Ether
common.HexToAddress("0xb71af880FC87F2aA099251A2224ef3f38BE7f451"): {Balance: new(big.Int).Mul(big.NewInt(1000000000000000000), big.NewInt(1000000000))}, // 1e9 Ether
},
NextValidators: []common.Address{
common.HexToAddress("0x2cff0b8e36522eba76f6f5c328d58581243882e4"),
common.HexToAddress("0x959994471dee37411f579dd2820a8743cba20f46"),
common.HexToAddress("0x977cfc676bb06daed7ddfa7711bcfe8d50c93081"),
common.HexToAddress("0xcd21538af6e33ff6fcf1e2ca20f771413004cfd3"),
common.HexToAddress("0x96f22a48DcD4dFb99A11560b24bee02F374cA77D"),
common.HexToAddress("0x560CD6c5054847c2AFCAae0dd9E34E22E6f47100"),
common.HexToAddress("0x3d2Bf29BaB6ec95422Eb143e856df3B0E775e50c"),
},
NextValidatorPowers: []uint64{1, 1, 1, 1},
NextValidatorPowers: []uint64{1, 1, 1},
}
}

Expand Down
8 changes: 6 additions & 2 deletions core/state_prefetcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,9 @@ func (p *statePrefetcher) Prefetch(block *types.Block, statedb *state.StateDB, c
return // Also invalid block, bail out
}
statedb.Prepare(tx.Hash(), i)
if err := precacheTransaction(msg, p.config, gaspool, statedb, header, evm); err != nil {
// get the external_call_result from uncles of block
expectExternalCallResult := block.GetExternalCallResult(tx.Hash())
if err := precacheTransaction(msg, p.config, gaspool, statedb, header, evm, expectExternalCallResult); err != nil {
return // Ugh, something went horribly wrong, bail out
}
// If we're pre-byzantium, pre-load trie nodes for the intermediate root
Expand All @@ -85,9 +87,11 @@ func (p *statePrefetcher) Prefetch(block *types.Block, statedb *state.StateDB, c
// precacheTransaction attempts to apply a transaction to the given state database
// and uses the input parameters for its environment. The goal is not to execute
// the transaction successfully, rather to warm up touched data slots.
func precacheTransaction(msg types.Message, config *params.ChainConfig, gaspool *GasPool, statedb *state.StateDB, header *types.Header, evm *vm.EVM) error {
func precacheTransaction(msg types.Message, config *params.ChainConfig, gaspool *GasPool, statedb *state.StateDB, header *types.Header, evm *vm.EVM, expectExternalCallResult []byte) error {
// Update the evm with the new transaction context.
evm.Reset(NewEVMTxContext(msg), statedb)
// set the external_call_result
evm.SetCrossChainCallResults(expectExternalCallResult)
// Add addresses to access list if applicable
_, err := ApplyMessage(evm, msg, gaspool)
return err
Expand Down
49 changes: 41 additions & 8 deletions core/state_processor.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package core

import (
"bytes"
"fmt"
"math/big"

Expand All @@ -27,6 +28,7 @@ import (
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/params"
)

Expand Down Expand Up @@ -56,7 +58,7 @@ func NewStateProcessor(config *params.ChainConfig, bc *BlockChain, engine consen
// Process returns the receipts and logs accumulated during the process and
// returns the amount of gas that was used in the process. If any of the
// transactions failed to execute due to insufficient gas it will return an error.
func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg vm.Config) (types.Receipts, []*types.Log, uint64, error) {
func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg vm.Config, usingClient bool) (types.Receipts, []*types.Log, uint64, error) {
var (
receipts types.Receipts
usedGas = new(uint64)
Expand All @@ -70,19 +72,46 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg
if p.config.DAOForkSupport && p.config.DAOForkBlock != nil && p.config.DAOForkBlock.Cmp(block.Number()) == 0 {
misc.ApplyDAOHardFork(statedb)
}

blockContext := NewEVMBlockContext(header, p.bc, nil)
// set the external_call_client from blockchain
if usingClient {
cfg.ExternalCallClient = p.bc.vmConfig.ExternalCallClient
}
vmenv := vm.NewEVM(blockContext, vm.TxContext{}, statedb, p.config, cfg)

// Iterate over and process the individual transactions
var uncleIndex int
for i, tx := range block.Transactions() {
msg, err := tx.AsMessage(types.MakeSigner(p.config, header.Number), header.BaseFee)
if err != nil {
return nil, nil, 0, fmt.Errorf("could not apply tx %d [%v]: %w", i, tx.Hash().Hex(), err)
}

statedb.Prepare(tx.Hash(), i)
receipt, err := applyTransaction(msg, p.config, p.bc, nil, gp, statedb, blockNumber, blockHash, tx, usedGas, vmenv)
// get the externalCallResult from uncle
var expectResult []byte
if len(block.Uncles()) > uncleIndex {
expectResult = block.Uncles()[uncleIndex].GetTxExternalCallResult(tx)
if expectResult != nil {
uncleIndex++
}
}

receipt, crossChainCallResult, err := applyTransaction(msg, p.config, p.bc, nil, gp, statedb, blockNumber, blockHash, tx, usedGas, vmenv, expectResult)
if err != nil {
return nil, nil, 0, fmt.Errorf("could not apply tx %d [%v]: %w", i, tx.Hash().Hex(), err)
}

if len(crossChainCallResult) > 0 || len(expectResult) > 0 {
if !bytes.Equal(expectResult, crossChainCallResult) {
log.Error("Failed to verify cross_chain_result and override the transaction.externalCallResult()", "txHash", tx.Hash().Hex(), "expect_cross_chain_result", common.Bytes2Hex(expectResult), "cross_chain_result", common.Bytes2Hex(crossChainCallResult))
return nil, nil, 0, fmt.Errorf("failed to verify cross_chain_result, tx: %s", tx.Hash().Hex())
} else {
log.Info("Verify cross_chain_result succeed", "txHash", tx.Hash().Hex(), "cross_chain_result", common.Bytes2Hex(crossChainCallResult))
}
}

receipts = append(receipts, receipt)
allLogs = append(allLogs, receipt.Logs...)
}
Expand All @@ -92,15 +121,18 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg
return receipts, allLogs, *usedGas, nil
}

func applyTransaction(msg types.Message, config *params.ChainConfig, bc ChainContext, author *common.Address, gp *GasPool, statedb *state.StateDB, blockNumber *big.Int, blockHash common.Hash, tx *types.Transaction, usedGas *uint64, evm *vm.EVM) (*types.Receipt, error) {
func applyTransaction(msg types.Message, config *params.ChainConfig, bc ChainContext, author *common.Address, gp *GasPool, statedb *state.StateDB, blockNumber *big.Int, blockHash common.Hash, tx *types.Transaction, usedGas *uint64, evm *vm.EVM, expectExternalCallResult []byte) (*types.Receipt, []byte, error) {
// Create a new context to be used in the EVM environment.
txContext := NewEVMTxContext(msg)
evm.Reset(txContext, statedb)

// Set cross_chain_call_result as expectExternalCallResult when external_call_client is nil and external_call_result is not empty
evm.SetCrossChainCallResults(expectExternalCallResult)

// Apply the transaction to the current state (included in the env).
result, err := ApplyMessage(evm, msg, gp)
if err != nil {
return nil, err
return nil, nil, err
}

// Update the state with pending changes.
Expand Down Expand Up @@ -134,20 +166,21 @@ func applyTransaction(msg types.Message, config *params.ChainConfig, bc ChainCon
receipt.BlockHash = blockHash
receipt.BlockNumber = blockNumber
receipt.TransactionIndex = uint(statedb.TxIndex())
return receipt, err
return receipt, result.CrossChainCallResults, err
}

// ApplyTransaction attempts to apply a transaction to the given state database
// and uses the input parameters for its environment. It returns the receipt
// for the transaction, gas used and an error if the transaction failed,
// indicating the block was invalid.
func ApplyTransaction(config *params.ChainConfig, bc ChainContext, author *common.Address, gp *GasPool, statedb *state.StateDB, header *types.Header, tx *types.Transaction, usedGas *uint64, cfg vm.Config) (*types.Receipt, error) {
func ApplyTransaction(config *params.ChainConfig, bc ChainContext, author *common.Address, gp *GasPool, statedb *state.StateDB, header *types.Header, tx *types.Transaction, usedGas *uint64, cfg vm.Config) (*types.Receipt, []byte, error) {
msg, err := tx.AsMessage(types.MakeSigner(config, header.Number), header.BaseFee)
if err != nil {
return nil, err
return nil, nil, err
}
// Create a new context to be used in the EVM environment
blockContext := NewEVMBlockContext(header, bc, author)
vmenv := vm.NewEVM(blockContext, vm.TxContext{}, statedb, config, cfg)
return applyTransaction(msg, config, bc, author, gp, statedb, header.Number, header.Hash(), tx, usedGas, vmenv)

return applyTransaction(msg, config, bc, author, gp, statedb, header.Number, header.Hash(), tx, usedGas, vmenv, nil)
}
Loading