mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-25 06:06:44 +00:00
Merge tag 'v1.11.4' into merge_v1.11.4
This commit is contained in:
commit
ba8aaf38b9
54 changed files with 1330 additions and 741 deletions
48
.travis.yml
48
.travis.yml
|
|
@ -57,30 +57,6 @@ jobs:
|
|||
script:
|
||||
- go run build/ci.go docker -image -manifest amd64,arm64 -upload ethereum/client-go
|
||||
|
||||
# This builder does the Ubuntu PPA upload
|
||||
- stage: build
|
||||
if: type = push
|
||||
os: linux
|
||||
dist: bionic
|
||||
go: 1.20.x
|
||||
env:
|
||||
- ubuntu-ppa
|
||||
- GO111MODULE=on
|
||||
git:
|
||||
submodules: false # avoid cloning ethereum/tests
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- devscripts
|
||||
- debhelper
|
||||
- dput
|
||||
- fakeroot
|
||||
- python-bzrlib
|
||||
- python-paramiko
|
||||
script:
|
||||
- echo '|1|7SiYPr9xl3uctzovOTj4gMwAC1M=|t6ReES75Bo/PxlOPJ6/GsGbTrM0= ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA0aKz5UTUndYgIGG7dQBV+HaeuEZJ2xPHo2DS2iSKvUL4xNMSAY4UguNW+pX56nAQmZKIZZ8MaEvSj6zMEDiq6HFfn5JcTlM80UwlnyKe8B8p7Nk06PPQLrnmQt5fh0HmEcZx+JU9TZsfCHPnX7MNz4ELfZE6cFsclClrKim3BHUIGq//t93DllB+h4O9LHjEUsQ1Sr63irDLSutkLJD6RXchjROXkNirlcNVHH/jwLWR5RcYilNX7S5bIkK8NlWPjsn/8Ua5O7I9/YoE97PpO6i73DTGLh5H9JN/SITwCKBkgSDWUt61uPK3Y11Gty7o2lWsBjhBUm2Y38CBsoGmBw==' >> ~/.ssh/known_hosts
|
||||
- go run build/ci.go debsrc -upload ethereum/ethereum -sftp-user geth-ci -signer "Go Ethereum Linux Builder <geth-ci@ethereum.org>"
|
||||
|
||||
# This builder does the Linux Azure uploads
|
||||
- stage: build
|
||||
if: type = push
|
||||
|
|
@ -162,6 +138,30 @@ jobs:
|
|||
script:
|
||||
- go run build/ci.go test $TEST_PACKAGES
|
||||
|
||||
# This builder does the Ubuntu PPA nightly uploads
|
||||
- stage: build
|
||||
if: type = cron
|
||||
os: linux
|
||||
dist: bionic
|
||||
go: 1.20.x
|
||||
env:
|
||||
- ubuntu-ppa
|
||||
- GO111MODULE=on
|
||||
git:
|
||||
submodules: false # avoid cloning ethereum/tests
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- devscripts
|
||||
- debhelper
|
||||
- dput
|
||||
- fakeroot
|
||||
- python-bzrlib
|
||||
- python-paramiko
|
||||
script:
|
||||
- echo '|1|7SiYPr9xl3uctzovOTj4gMwAC1M=|t6ReES75Bo/PxlOPJ6/GsGbTrM0= ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA0aKz5UTUndYgIGG7dQBV+HaeuEZJ2xPHo2DS2iSKvUL4xNMSAY4UguNW+pX56nAQmZKIZZ8MaEvSj6zMEDiq6HFfn5JcTlM80UwlnyKe8B8p7Nk06PPQLrnmQt5fh0HmEcZx+JU9TZsfCHPnX7MNz4ELfZE6cFsclClrKim3BHUIGq//t93DllB+h4O9LHjEUsQ1Sr63irDLSutkLJD6RXchjROXkNirlcNVHH/jwLWR5RcYilNX7S5bIkK8NlWPjsn/8Ua5O7I9/YoE97PpO6i73DTGLh5H9JN/SITwCKBkgSDWUt61uPK3Y11Gty7o2lWsBjhBUm2Y38CBsoGmBw==' >> ~/.ssh/known_hosts
|
||||
- go run build/ci.go debsrc -upload ethereum/ethereum -sftp-user geth-ci -signer "Go Ethereum Linux Builder <geth-ci@ethereum.org>"
|
||||
|
||||
# This builder does the Azure archive purges to avoid accumulating junk
|
||||
- stage: build
|
||||
if: type = cron
|
||||
|
|
|
|||
|
|
@ -644,20 +644,33 @@ func (b *SimulatedBackend) callContract(ctx context.Context, call ethereum.CallM
|
|||
if call.Value == nil {
|
||||
call.Value = new(big.Int)
|
||||
}
|
||||
|
||||
// Set infinite balance to the fake caller account.
|
||||
from := stateDB.GetOrNewStateObject(call.From)
|
||||
from.SetBalance(math.MaxBig256)
|
||||
// Execute the call.
|
||||
msg := callMsg{call}
|
||||
|
||||
txContext := core.NewEVMTxContext(msg)
|
||||
evmContext := core.NewEVMBlockContext(header, b.blockchain, nil)
|
||||
// Execute the call.
|
||||
msg := &core.Message{
|
||||
From: call.From,
|
||||
To: call.To,
|
||||
Value: call.Value,
|
||||
GasLimit: call.Gas,
|
||||
GasPrice: call.GasPrice,
|
||||
GasFeeCap: call.GasFeeCap,
|
||||
GasTipCap: call.GasTipCap,
|
||||
Data: call.Data,
|
||||
AccessList: call.AccessList,
|
||||
SkipAccountChecks: true,
|
||||
}
|
||||
|
||||
// Create a new environment which holds all relevant information
|
||||
// about the transaction and calling mechanisms.
|
||||
txContext := core.NewEVMTxContext(msg)
|
||||
evmContext := core.NewEVMBlockContext(header, b.blockchain, nil)
|
||||
vmEnv := vm.NewEVM(evmContext, txContext, stateDB, b.config, vm.Config{NoBaseFee: true})
|
||||
gasPool := new(core.GasPool).AddGas(math.MaxUint64)
|
||||
|
||||
return core.NewStateTransition(vmEnv, msg, gasPool).TransitionDb()
|
||||
return core.ApplyMessage(vmEnv, msg, gasPool)
|
||||
}
|
||||
|
||||
// SendTransaction updates the pending block to include the given transaction.
|
||||
|
|
@ -821,24 +834,6 @@ func (b *SimulatedBackend) Blockchain() *core.BlockChain {
|
|||
return b.blockchain
|
||||
}
|
||||
|
||||
// callMsg implements core.Message to allow passing it as a transaction simulator.
|
||||
type callMsg struct {
|
||||
ethereum.CallMsg
|
||||
}
|
||||
|
||||
func (m callMsg) From() common.Address { return m.CallMsg.From }
|
||||
func (m callMsg) Nonce() uint64 { return 0 }
|
||||
func (m callMsg) IsFake() bool { return true }
|
||||
func (m callMsg) IsPre() bool { return false }
|
||||
func (m callMsg) To() *common.Address { return m.CallMsg.To }
|
||||
func (m callMsg) GasPrice() *big.Int { return m.CallMsg.GasPrice }
|
||||
func (m callMsg) GasFeeCap() *big.Int { return m.CallMsg.GasFeeCap }
|
||||
func (m callMsg) GasTipCap() *big.Int { return m.CallMsg.GasTipCap }
|
||||
func (m callMsg) Gas() uint64 { return m.CallMsg.Gas }
|
||||
func (m callMsg) Value() *big.Int { return m.CallMsg.Value }
|
||||
func (m callMsg) Data() []byte { return m.CallMsg.Data }
|
||||
func (m callMsg) AccessList() types.AccessList { return m.CallMsg.AccessList }
|
||||
|
||||
// filterBackend implements filters.Backend to support filtering for logs without
|
||||
// taking bloom-bits acceleration structures into account.
|
||||
type filterBackend struct {
|
||||
|
|
|
|||
|
|
@ -163,7 +163,7 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
|
|||
}
|
||||
|
||||
for i, tx := range txs {
|
||||
msg, err := tx.AsMessage(signer, pre.Env.BaseFee)
|
||||
msg, err := core.TransactionToMessage(tx, signer, pre.Env.BaseFee)
|
||||
if err != nil {
|
||||
log.Warn("rejected tx", "index", i, "hash", tx.Hash(), "error", err)
|
||||
rejectedTxs = append(rejectedTxs, &rejectedTx{i, err.Error()})
|
||||
|
|
@ -188,7 +188,7 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
|
|||
msgResult, err := core.ApplyMessage(evm, msg, gaspool)
|
||||
if err != nil {
|
||||
statedb.RevertToSnapshot(snapshot)
|
||||
log.Info("rejected tx", "index", i, "hash", tx.Hash(), "from", msg.From(), "error", err)
|
||||
log.Info("rejected tx", "index", i, "hash", tx.Hash(), "from", msg.From, "error", err)
|
||||
rejectedTxs = append(rejectedTxs, &rejectedTx{i, err.Error()})
|
||||
gaspool.SetGas(prevGas)
|
||||
continue
|
||||
|
|
@ -220,7 +220,7 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
|
|||
receipt.GasUsed = msgResult.UsedGas
|
||||
|
||||
// If the transaction created a contract, store the creation address in the receipt.
|
||||
if msg.To() == nil {
|
||||
if msg.To == nil {
|
||||
receipt.ContractAddress = crypto.CreateAddress(evm.TxContext.Origin, tx.Nonce())
|
||||
}
|
||||
|
||||
|
|
|
|||
134
cmd/evm/testdata/10/readme.md
vendored
134
cmd/evm/testdata/10/readme.md
vendored
|
|
@ -9,71 +9,77 @@ INFO [05-09|22:11:59.436] rejected tx index=3 hash=
|
|||
Output:
|
||||
```json
|
||||
{
|
||||
"alloc": {
|
||||
"0x1111111111111111111111111111111111111111": {
|
||||
"code": "0xfe",
|
||||
"balance": "0x10000000000",
|
||||
"nonce": "0x1"
|
||||
"alloc": {
|
||||
"0x1111111111111111111111111111111111111111": {
|
||||
"code": "0xfe",
|
||||
"balance": "0x10000000000",
|
||||
"nonce": "0x1"
|
||||
},
|
||||
"0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b": {
|
||||
"balance": "0x10000000000",
|
||||
"nonce": "0x1"
|
||||
},
|
||||
"0xd02d72e067e77158444ef2020ff2d325f929b363": {
|
||||
"balance": "0xff5beffffc95",
|
||||
"nonce": "0x4"
|
||||
}
|
||||
},
|
||||
"0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b": {
|
||||
"balance": "0x10000000000",
|
||||
"nonce": "0x1"
|
||||
},
|
||||
"0xd02d72e067e77158444ef2020ff2d325f929b363": {
|
||||
"balance": "0xff5beffffc95",
|
||||
"nonce": "0x4"
|
||||
"result": {
|
||||
"stateRoot": "0xf91a7ec08e4bfea88719aab34deabb000c86902360532b52afa9599d41f2bb8b",
|
||||
"txRoot": "0xda925f2306a52fa24c15d5cd212d736ee016415fd8dd0c45fd368de7917d64bb",
|
||||
"receiptsRoot": "0x439a25f7fc424c10fb1f89800e4aa1df74156b137239d9ac3eaa7c911c353cd5",
|
||||
"logsHash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
||||
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
||||
"receipts": [
|
||||
{
|
||||
"type": "0x2",
|
||||
"root": "0x",
|
||||
"status": "0x0",
|
||||
"cumulativeGasUsed": "0x10000001",
|
||||
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
||||
"logs": null,
|
||||
"transactionHash": "0x88980f6efcc5358d9c359663e7b9414722d430497637340ea056b076bc206701",
|
||||
"contractAddress": "0x0000000000000000000000000000000000000000",
|
||||
"gasUsed": "0x10000001",
|
||||
"blockHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"transactionIndex": "0x0"
|
||||
},
|
||||
{
|
||||
"type": "0x2",
|
||||
"root": "0x",
|
||||
"status": "0x0",
|
||||
"cumulativeGasUsed": "0x20000001",
|
||||
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
||||
"logs": null,
|
||||
"transactionHash": "0xd7bf3886f4e2aef74d525ae072c680f3846f550254401b67cbfda4a233757582",
|
||||
"contractAddress": "0x0000000000000000000000000000000000000000",
|
||||
"gasUsed": "0x10000000",
|
||||
"blockHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"transactionIndex": "0x1"
|
||||
},
|
||||
{
|
||||
"type": "0x2",
|
||||
"root": "0x",
|
||||
"status": "0x0",
|
||||
"cumulativeGasUsed": "0x30000001",
|
||||
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
||||
"logs": null,
|
||||
"transactionHash": "0x50308296760f01f1eeec7500e9e73cad67469249b1f59e9a9f55e6625a4923db",
|
||||
"contractAddress": "0x0000000000000000000000000000000000000000",
|
||||
"gasUsed": "0x10000000",
|
||||
"blockHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"transactionIndex": "0x2"
|
||||
}
|
||||
],
|
||||
"rejected": [
|
||||
{
|
||||
"index": 3,
|
||||
"error": "gas limit reached"
|
||||
}
|
||||
],
|
||||
"currentDifficulty": "0x20000",
|
||||
"gasUsed": "0x30000001",
|
||||
"currentBaseFee": "0x36b"
|
||||
}
|
||||
},
|
||||
"result": {
|
||||
"stateRoot": "0xf91a7ec08e4bfea88719aab34deabb000c86902360532b52afa9599d41f2bb8b",
|
||||
"txRoot": "0xda925f2306a52fa24c15d5cd212d736ee016415fd8dd0c45fd368de7917d64bb",
|
||||
"receiptRoot": "0x439a25f7fc424c10fb1f89800e4aa1df74156b137239d9ac3eaa7c911c353cd5",
|
||||
"logsHash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
||||
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
||||
"receipts": [
|
||||
{
|
||||
"type": "0x2",
|
||||
"root": "0x",
|
||||
"status": "0x0",
|
||||
"cumulativeGasUsed": "0x10000001",
|
||||
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
||||
"logs": null,
|
||||
"transactionHash": "0x88980f6efcc5358d9c359663e7b9414722d430497637340ea056b076bc206701",
|
||||
"contractAddress": "0x0000000000000000000000000000000000000000",
|
||||
"gasUsed": "0x10000001",
|
||||
"blockHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"transactionIndex": "0x0"
|
||||
},
|
||||
{
|
||||
"type": "0x2",
|
||||
"root": "0x",
|
||||
"status": "0x0",
|
||||
"cumulativeGasUsed": "0x20000001",
|
||||
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
||||
"logs": null,
|
||||
"transactionHash": "0xd7bf3886f4e2aef74d525ae072c680f3846f550254401b67cbfda4a233757582",
|
||||
"contractAddress": "0x0000000000000000000000000000000000000000",
|
||||
"gasUsed": "0x10000000",
|
||||
"blockHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"transactionIndex": "0x1"
|
||||
},
|
||||
{
|
||||
"type": "0x2",
|
||||
"root": "0x",
|
||||
"status": "0x0",
|
||||
"cumulativeGasUsed": "0x30000001",
|
||||
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
||||
"logs": null,
|
||||
"transactionHash": "0x50308296760f01f1eeec7500e9e73cad67469249b1f59e9a9f55e6625a4923db",
|
||||
"contractAddress": "0x0000000000000000000000000000000000000000",
|
||||
"gasUsed": "0x10000000",
|
||||
"blockHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"transactionIndex": "0x2"
|
||||
}
|
||||
],
|
||||
"rejected": [
|
||||
3
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
|
|
|||
45
cmd/evm/testdata/12/readme.md
vendored
45
cmd/evm/testdata/12/readme.md
vendored
|
|
@ -11,29 +11,32 @@ dir=./testdata/12 && ./evm t8n --state.fork=London --input.alloc=$dir/alloc.json
|
|||
With the fix applied, the result is:
|
||||
```
|
||||
dir=./testdata/12 && ./evm t8n --state.fork=London --input.alloc=$dir/alloc.json --input.txs=$dir/txs.json --input.env=$dir/env.json --output.alloc=stdout --output.result=stdout
|
||||
INFO [07-21|19:03:50.276] rejected tx index=0 hash=ccc996..d83435 from=0xa94f5374Fce5edBC8E2a8697C15331677e6EbF0B error="insufficient funds for gas * price + value: address 0xa94f5374Fce5edBC8E2a8697C15331677e6EbF0B have 84000000 want 84000032"
|
||||
INFO [07-21|19:03:50.276] Trie dumping started root=e05f81..6597a5
|
||||
INFO [07-21|19:03:50.276] Trie dumping complete accounts=1 elapsed="39.549µs"
|
||||
INFO [03-09|10:43:12.649] rejected tx index=0 hash=ccc996..d83435 from=0xa94f5374Fce5edBC8E2a8697C15331677e6EbF0B error="insufficient funds for gas * price + value: address 0xa94f5374Fce5edBC8E2a8697C15331677e6EbF0B have 84000000 want 84000032"
|
||||
INFO [03-09|10:43:12.650] Trie dumping started root=e05f81..6597a5
|
||||
INFO [03-09|10:43:12.650] Trie dumping complete accounts=1 elapsed="46.393µs"
|
||||
{
|
||||
"alloc": {
|
||||
"0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b": {
|
||||
"balance": "0x501bd00"
|
||||
"alloc": {
|
||||
"0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b": {
|
||||
"balance": "0x501bd00"
|
||||
}
|
||||
},
|
||||
"result": {
|
||||
"stateRoot": "0xe05f81f8244a76503ceec6f88abfcd03047a612a1001217f37d30984536597a5",
|
||||
"txRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
||||
"receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
||||
"logsHash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
||||
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
||||
"receipts": [],
|
||||
"rejected": [
|
||||
{
|
||||
"index": 0,
|
||||
"error": "insufficient funds for gas * price + value: address 0xa94f5374Fce5edBC8E2a8697C15331677e6EbF0B have 84000000 want 84000032"
|
||||
}
|
||||
],
|
||||
"currentDifficulty": "0x20000",
|
||||
"gasUsed": "0x0",
|
||||
"currentBaseFee": "0x20"
|
||||
}
|
||||
},
|
||||
"result": {
|
||||
"stateRoot": "0xe05f81f8244a76503ceec6f88abfcd03047a612a1001217f37d30984536597a5",
|
||||
"txRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
||||
"receiptRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
||||
"logsHash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
||||
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
||||
"receipts": [],
|
||||
"rejected": [
|
||||
{
|
||||
"index": 0,
|
||||
"error": "insufficient funds for gas * price + value: address 0xa94f5374Fce5edBC8E2a8697C15331677e6EbF0B have 84000000 want 84000032"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
|
|
|||
24
cmd/evm/testdata/14/readme.md
vendored
24
cmd/evm/testdata/14/readme.md
vendored
|
|
@ -5,36 +5,40 @@ This test shows how the `evm t8n` can be used to calculate the (ethash) difficul
|
|||
Calculating it (with an empty set of txs) using `London` rules (and no provided unclehash for the parent block):
|
||||
```
|
||||
[user@work evm]$ ./evm t8n --input.alloc=./testdata/14/alloc.json --input.txs=./testdata/14/txs.json --input.env=./testdata/14/env.json --output.result=stdout --state.fork=London
|
||||
INFO [08-30|20:43:09.352] Trie dumping started root=6f0588..7f4bdc
|
||||
INFO [08-30|20:43:09.352] Trie dumping complete accounts=2 elapsed="82.533µs"
|
||||
INFO [08-30|20:43:09.352] Wrote file file=alloc.json
|
||||
INFO [03-09|10:43:57.070] Trie dumping started root=6f0588..7f4bdc
|
||||
INFO [03-09|10:43:57.070] Trie dumping complete accounts=2 elapsed="214.663µs"
|
||||
INFO [03-09|10:43:57.071] Wrote file file=alloc.json
|
||||
{
|
||||
"result": {
|
||||
"stateRoot": "0x6f058887ca01549716789c380ede95aecc510e6d1fdc4dbf67d053c7c07f4bdc",
|
||||
"txRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
||||
"receiptRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
||||
"receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
||||
"logsHash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
||||
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
||||
"receipts": [],
|
||||
"currentDifficulty": "0x2000020000000"
|
||||
"currentDifficulty": "0x2000020000000",
|
||||
"gasUsed": "0x0",
|
||||
"currentBaseFee": "0x500"
|
||||
}
|
||||
}
|
||||
```
|
||||
Same thing, but this time providing a non-empty (and non-`emptyKeccak`) unclehash, which leads to a slightly different result:
|
||||
```
|
||||
[user@work evm]$ ./evm t8n --input.alloc=./testdata/14/alloc.json --input.txs=./testdata/14/txs.json --input.env=./testdata/14/env.uncles.json --output.result=stdout --state.fork=London
|
||||
INFO [08-30|20:44:33.102] Trie dumping started root=6f0588..7f4bdc
|
||||
INFO [08-30|20:44:33.102] Trie dumping complete accounts=2 elapsed="72.91µs"
|
||||
INFO [08-30|20:44:33.102] Wrote file file=alloc.json
|
||||
INFO [03-09|10:44:20.511] Trie dumping started root=6f0588..7f4bdc
|
||||
INFO [03-09|10:44:20.511] Trie dumping complete accounts=2 elapsed="184.319µs"
|
||||
INFO [03-09|10:44:20.512] Wrote file file=alloc.json
|
||||
{
|
||||
"result": {
|
||||
"stateRoot": "0x6f058887ca01549716789c380ede95aecc510e6d1fdc4dbf67d053c7c07f4bdc",
|
||||
"txRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
||||
"receiptRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
||||
"receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
||||
"logsHash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
||||
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
||||
"receipts": [],
|
||||
"currentDifficulty": "0x1ff8020000000"
|
||||
"currentDifficulty": "0x1ff8020000000",
|
||||
"gasUsed": "0x0",
|
||||
"currentBaseFee": "0x500"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
|
|
|||
16
cmd/evm/testdata/19/readme.md
vendored
16
cmd/evm/testdata/19/readme.md
vendored
|
|
@ -6,4 +6,20 @@ this time on `GrayGlacier` (Eip 5133).
|
|||
Calculating it (with an empty set of txs) using `GrayGlacier` rules (and no provided unclehash for the parent block):
|
||||
```
|
||||
[user@work evm]$ ./evm t8n --input.alloc=./testdata/19/alloc.json --input.txs=./testdata/19/txs.json --input.env=./testdata/19/env.json --output.result=stdout --state.fork=GrayGlacier
|
||||
INFO [03-09|10:45:26.777] Trie dumping started root=6f0588..7f4bdc
|
||||
INFO [03-09|10:45:26.777] Trie dumping complete accounts=2 elapsed="176.471µs"
|
||||
INFO [03-09|10:45:26.777] Wrote file file=alloc.json
|
||||
{
|
||||
"result": {
|
||||
"stateRoot": "0x6f058887ca01549716789c380ede95aecc510e6d1fdc4dbf67d053c7c07f4bdc",
|
||||
"txRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
||||
"receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
||||
"logsHash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
||||
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
||||
"receipts": [],
|
||||
"currentDifficulty": "0x2000000004000",
|
||||
"gasUsed": "0x0",
|
||||
"currentBaseFee": "0x500"
|
||||
}
|
||||
}
|
||||
```
|
||||
370
cmd/evm/testdata/7/readme.md
vendored
370
cmd/evm/testdata/7/readme.md
vendored
|
|
@ -3,5 +3,373 @@ DAO-transition works
|
|||
|
||||
Example:
|
||||
```
|
||||
./statet8n --input.alloc=./testdata/7/alloc.json --input.txs=./testdata/7/txs.json --input.env=./testdata/7/env.json --output.alloc=stdout --state.fork=HomesteadToDaoAt5
|
||||
./evm t8n --input.alloc=./testdata/7/alloc.json --input.txs=./testdata/7/txs.json --input.env=./testdata/7/env.json --output.alloc=stdout --state.fork=HomesteadToDaoAt5
|
||||
INFO [03-09|10:47:37.255] Trie dumping started root=157847..2891b7
|
||||
INFO [03-09|10:47:37.256] Trie dumping complete accounts=120 elapsed="715.635µs"
|
||||
INFO [03-09|10:47:37.256] Wrote file file=result.json
|
||||
{
|
||||
"alloc": {
|
||||
"0x005f5cee7a43331d5a3d3eec71305925a62f34b6": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0x0101f3be8ebb4bbd39a2e3b9a3639d4259832fd9": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0x057b56736d32b86616a10f619859c6cd6f59092a": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0x06706dd3f2c9abf0a21ddcc6941d9b86f0596936": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0x0737a6b837f97f46ebade41b9bc3e1c509c85c53": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0x07f5c1e1bc2c93e0402f23341973a0e043f7bf8a": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0x0e0da70933f4c7849fc0d203f5d1d43b9ae4532d": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0x0ff30d6de14a8224aa97b78aea5388d1c51c1f00": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0x12e626b0eebfe86a56d633b9864e389b45dcb260": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0x1591fc0f688c81fbeb17f5426a162a7024d430c2": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0x17802f43a0137c506ba92291391a8a8f207f487d": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0x1975bd06d486162d5dc297798dfc41edd5d160a7": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0x1ca6abd14d30affe533b24d7a21bff4c2d5e1f3b": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0x1cba23d343a983e9b5cfd19496b9a9701ada385f": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0x200450f06520bdd6c527622a273333384d870efb": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0x21c7fdb9ed8d291d79ffd82eb2c4356ec0d81241": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0x23b75c2f6791eef49c69684db4c6c1f93bf49a50": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0x24c4d950dfd4dd1902bbed3508144a54542bba94": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0x253488078a4edf4d6f42f113d1e62836a942cf1a": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0x27b137a85656544b1ccb5a0f2e561a5703c6a68f": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0x2a5ed960395e2a49b1c758cef4aa15213cfd874c": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0x2b3455ec7fedf16e646268bf88846bd7a2319bb2": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0x2c19c7f9ae8b751e37aeb2d93a699722395ae18f": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0x304a554a310c7e546dfe434669c62820b7d83490": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0x319f70bab6845585f412ec7724b744fec6095c85": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0x35a051a0010aba705c9008d7a7eff6fb88f6ea7b": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0x3ba4d81db016dc2890c81f3acec2454bff5aada5": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0x3c02a7bc0391e86d91b7d144e61c2c01a25a79c5": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0x40b803a9abce16f50f36a77ba41180eb90023925": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0x440c59b325d2997a134c2c7c60a8c61611212bad": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0x4486a3d68fac6967006d7a517b889fd3f98c102b": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0x4613f3bca5c44ea06337a9e439fbc6d42e501d0a": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0x47e7aa56d6bdf3f36be34619660de61275420af8": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0x4863226780fe7c0356454236d3b1c8792785748d": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0x492ea3bb0f3315521c31f273e565b868fc090f17": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0x4cb31628079fb14e4bc3cd5e30c2f7489b00960c": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0x4deb0033bb26bc534b197e61d19e0733e5679784": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0x4fa802324e929786dbda3b8820dc7834e9134a2a": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0x4fd6ace747f06ece9c49699c7cabc62d02211f75": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0x51e0ddd9998364a2eb38588679f0d2c42653e4a6": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0x52c5317c848ba20c7504cb2c8052abd1fde29d03": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0x542a9515200d14b68e934e9830d91645a980dd7a": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0x5524c55fb03cf21f549444ccbecb664d0acad706": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0x579a80d909f346fbfb1189493f521d7f48d52238": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0x58b95c9a9d5d26825e70a82b6adb139d3fd829eb": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0x5c6e67ccd5849c0d29219c4f95f1a7a93b3f5dc5": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0x5c8536898fbb74fc7445814902fd08422eac56d0": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0x5d2b2e6fcbe3b11d26b525e085ff818dae332479": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0x5dc28b15dffed94048d73806ce4b7a4612a1d48f": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0x5f9f3392e9f62f63b8eac0beb55541fc8627f42c": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0x6131c42fa982e56929107413a9d526fd99405560": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0x6231b6d0d5e77fe001c2a460bd9584fee60d409b": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0x627a0a960c079c21c34f7612d5d230e01b4ad4c7": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0x63ed5a272de2f6d968408b4acb9024f4cc208ebf": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0x6966ab0d485353095148a2155858910e0965b6f9": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0x6b0c4d41ba9ab8d8cfb5d379c69a612f2ced8ecb": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0x6d87578288b6cb5549d5076a207456a1f6a63dc0": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0x6f6704e5a10332af6672e50b3d9754dc460dfa4d": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0x7602b46df5390e432ef1c307d4f2c9ff6d65cc97": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0x779543a0491a837ca36ce8c635d6154e3c4911a6": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0x77ca7b50b6cd7e2f3fa008e24ab793fd56cb15f6": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0x782495b7b3355efb2833d56ecb34dc22ad7dfcc4": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0x807640a13483f8ac783c557fcdf27be11ea4ac7a": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0x8163e7fb499e90f8544ea62bbf80d21cd26d9efd": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0x84ef4b2357079cd7a7c69fd7a37cd0609a679106": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0x86af3e9626fce1957c82e88cbf04ddf3a2ed7915": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0x8a8eafb1cf62bfbeb1741769dae1a9dd47996192": {
|
||||
"balance": "0xfeedbead"
|
||||
},
|
||||
"0x8d9edb3054ce5c5774a420ac37ebae0ac02343c6": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0x914d1b8b43e92723e64fd0a06f5bdb8dd9b10c79": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0x97f43a37f595ab5dd318fb46e7a155eae057317a": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0x9aa008f65de0b923a2a4f02012ad034a5e2e2192": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0x9c15b54878ba618f494b38f0ae7443db6af648ba": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0x9c50426be05db97f5d64fc54bf89eff947f0a321": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0x9da397b9e80755301a3b32173283a91c0ef6c87e": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0x9ea779f907f0b315b364b0cfc39a0fde5b02a416": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0x9f27daea7aca0aa0446220b98d028715e3bc803d": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0x9fcd2deaff372a39cc679d5c5e4de7bafb0b1339": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0xa2f1ccba9395d7fcb155bba8bc92db9bafaeade7": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0xa3acf3a1e16b1d7c315e23510fdd7847b48234f6": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0xa5dc5acd6a7968a4554d89d65e59b7fd3bff0f90": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0xa82f360a8d3455c5c41366975bde739c37bfeb8a": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b": {
|
||||
"balance": "0x5ffd4878be161d74",
|
||||
"nonce": "0xac"
|
||||
},
|
||||
"0xac1ecab32727358dba8962a0f3b261731aad9723": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0xaccc230e8a6e5be9160b8cdf2864dd2a001c28b6": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0xacd87e28b0c9d1254e868b81cba4cc20d9a32225": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0xadf80daec7ba8dcf15392f1ac611fff65d94f880": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0xaeeb8ff27288bdabc0fa5ebb731b6f409507516c": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0xb136707642a4ea12fb4bae820f03d2562ebff487": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0xb2c6f0dfbb716ac562e2d85d6cb2f8d5ee87603e": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0xb3fb0e5aba0e20e5c49d252dfd30e102b171a425": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0xb52042c8ca3f8aa246fa79c3feaa3d959347c0ab": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0xb9637156d330c0d605a791f1c31ba5890582fe1c": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0xbb9bc244d798123fde783fcc1c72d3bb8c189413": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0xbc07118b9ac290e4622f5e77a0853539789effbe": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0xbcf899e6c7d9d5a215ab1e3444c86806fa854c76": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0xbe8539bfe837b67d1282b2b1d61c3f723966f049": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0xbf4ed7b27f1d666546e30d74d50d173d20bca754": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0xc4bbd073882dd2add2424cf47d35213405b01324": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0xc94f5374fce5edbc8e2a8697c15331677e6ebf0b": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0xca544e5c4687d109611d0f8f928b53a25af72448": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0xcbb9d3703e651b0d496cdefb8b92c25aeb2171f7": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0xcc34673c6c40e791051898567a1222daf90be287": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0xceaeb481747ca6c540a000c1f3641f8cef161fa7": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0xd131637d5275fd1a68a3200f4ad25c71a2a9522e": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0xd164b088bd9108b60d0ca3751da4bceb207b0782": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0xd1ac8b1ef1b69ff51d1d401a476e7e612414f091": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0xd343b217de44030afaa275f54d31a9317c7f441e": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0xd4fe7bc31cedb7bfb8a345f31e668033056b2728": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0xd9aef3a1e38a39c16b31d1ace71bca8ef58d315b": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0xda2fef9e4a3230988ff17df2165440f37e8b1708": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0xdbe9b615a3ae8709af8b93336ce9b477e4ac0940": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0xe308bd1ac5fda103967359b2712dd89deffb7973": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0xe4ae1efdfc53b73893af49113d8694a057b9c0d1": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0xec8e57756626fdc07c63ad2eafbd28d08e7b0ca5": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0xecd135fa4f61a655311e86238c92adcd779555d2": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0xf0b1aa0eb660754448a7937c022e30aa692fe0c5": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0xf1385fb24aad0cd7432824085e42aff90886fef5": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0xf14c14075d6c4ed84b86798af0956deef67365b5": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0xf4c64518ea10f995918a454158c6b61407ea345c": {
|
||||
"balance": "0x0"
|
||||
},
|
||||
"0xfe24cdd8648121a43a7c86d289be4dd2951ed49f": {
|
||||
"balance": "0x0"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
38
cmd/evm/testdata/8/readme.md
vendored
38
cmd/evm/testdata/8/readme.md
vendored
|
|
@ -23,41 +23,37 @@ There are three transactions, each invokes the contract above.
|
|||
|
||||
Running it yields:
|
||||
```
|
||||
dir=./testdata/8 && ./evm t8n --state.fork=Berlin --input.alloc=$dir/alloc.json --input.txs=$dir/txs.json --input.env=$dir/env.json --trace && cat trace-* | grep SLOAD
|
||||
{"pc":1,"op":84,"gas":"0x484be","gasCost":"0x834","memory":"0x","memSize":0,"stack":["0x0"],"returnStack":[],"returnData":"0x","depth":1,"refund":0,"opName":"SLOAD","error":""}
|
||||
{"pc":4,"op":84,"gas":"0x47c86","gasCost":"0x834","memory":"0x","memSize":0,"stack":["0x3"],"returnStack":[],"returnData":"0x","depth":1,"refund":0,"opName":"SLOAD","error":""}
|
||||
{"pc":1,"op":84,"gas":"0x49cf6","gasCost":"0x834","memory":"0x","memSize":0,"stack":["0x0"],"returnStack":[],"returnData":"0x","depth":1,"refund":0,"opName":"SLOAD","error":""}
|
||||
{"pc":4,"op":84,"gas":"0x494be","gasCost":"0x834","memory":"0x","memSize":0,"stack":["0x3"],"returnStack":[],"returnData":"0x","depth":1,"refund":0,"opName":"SLOAD","error":""}
|
||||
{"pc":1,"op":84,"gas":"0x484be","gasCost":"0x64","memory":"0x","memSize":0,"stack":["0x0"],"returnStack":[],"returnData":"0x","depth":1,"refund":0,"opName":"SLOAD","error":""}
|
||||
{"pc":4,"op":84,"gas":"0x48456","gasCost":"0x64","memory":"0x","memSize":0,"stack":["0x3"],"returnStack":[],"returnData":"0x","depth":1,"refund":0,"opName":"SLOAD","error":""}
|
||||
|
||||
dir=./testdata/8 && ./evm t8n --state.fork=Berlin --input.alloc=$dir/alloc.json --input.txs=$dir/txs.json --input.env=$dir/env.json --trace 2>/dev/null && cat trace-* | grep SLOAD
|
||||
{"pc":1,"op":84,"gas":"0x484be","gasCost":"0x834","memSize":0,"stack":["0x0"],"depth":1,"refund":0,"opName":"SLOAD"}
|
||||
{"pc":4,"op":84,"gas":"0x47c86","gasCost":"0x834","memSize":0,"stack":["0x3"],"depth":1,"refund":0,"opName":"SLOAD"}
|
||||
{"pc":1,"op":84,"gas":"0x49cf6","gasCost":"0x834","memSize":0,"stack":["0x0"],"depth":1,"refund":0,"opName":"SLOAD"}
|
||||
{"pc":4,"op":84,"gas":"0x494be","gasCost":"0x834","memSize":0,"stack":["0x3"],"depth":1,"refund":0,"opName":"SLOAD"}
|
||||
{"pc":1,"op":84,"gas":"0x484be","gasCost":"0x64","memSize":0,"stack":["0x0"],"depth":1,"refund":0,"opName":"SLOAD"}
|
||||
{"pc":4,"op":84,"gas":"0x48456","gasCost":"0x64","memSize":0,"stack":["0x3"],"depth":1,"refund":0,"opName":"SLOAD"}
|
||||
```
|
||||
|
||||
Simlarly, we can provide the input transactions via `stdin` instead of as file:
|
||||
|
||||
```
|
||||
dir=./testdata/8 \
|
||||
$ dir=./testdata/8 \
|
||||
&& cat $dir/txs.json | jq "{txs: .}" \
|
||||
| ./evm t8n --state.fork=Berlin \
|
||||
--input.alloc=$dir/alloc.json \
|
||||
--input.txs=stdin \
|
||||
--input.env=$dir/env.json \
|
||||
--trace \
|
||||
2>/dev/null \
|
||||
&& cat trace-* | grep SLOAD
|
||||
|
||||
{"pc":1,"op":84,"gas":"0x484be","gasCost":"0x834","memory":"0x","memSize":0,"stack":["0x0"],"returnStack":[],"returnData":"0x","depth":1,"refund":0,"opName":"SLOAD","error":""}
|
||||
{"pc":4,"op":84,"gas":"0x47c86","gasCost":"0x834","memory":"0x","memSize":0,"stack":["0x3"],"returnStack":[],"returnData":"0x","depth":1,"refund":0,"opName":"SLOAD","error":""}
|
||||
{"pc":1,"op":84,"gas":"0x49cf6","gasCost":"0x834","memory":"0x","memSize":0,"stack":["0x0"],"returnStack":[],"returnData":"0x","depth":1,"refund":0,"opName":"SLOAD","error":""}
|
||||
{"pc":4,"op":84,"gas":"0x494be","gasCost":"0x834","memory":"0x","memSize":0,"stack":["0x3"],"returnStack":[],"returnData":"0x","depth":1,"refund":0,"opName":"SLOAD","error":""}
|
||||
{"pc":1,"op":84,"gas":"0x484be","gasCost":"0x64","memory":"0x","memSize":0,"stack":["0x0"],"returnStack":[],"returnData":"0x","depth":1,"refund":0,"opName":"SLOAD","error":""}
|
||||
{"pc":4,"op":84,"gas":"0x48456","gasCost":"0x64","memory":"0x","memSize":0,"stack":["0x3"],"returnStack":[],"returnData":"0x","depth":1,"refund":0,"opName":"SLOAD","error":""}
|
||||
{"pc":1,"op":84,"gas":"0x484be","gasCost":"0x834","memSize":0,"stack":["0x0"],"depth":1,"refund":0,"opName":"SLOAD"}
|
||||
{"pc":4,"op":84,"gas":"0x47c86","gasCost":"0x834","memSize":0,"stack":["0x3"],"depth":1,"refund":0,"opName":"SLOAD"}
|
||||
{"pc":1,"op":84,"gas":"0x49cf6","gasCost":"0x834","memSize":0,"stack":["0x0"],"depth":1,"refund":0,"opName":"SLOAD"}
|
||||
{"pc":4,"op":84,"gas":"0x494be","gasCost":"0x834","memSize":0,"stack":["0x3"],"depth":1,"refund":0,"opName":"SLOAD"}
|
||||
{"pc":1,"op":84,"gas":"0x484be","gasCost":"0x64","memSize":0,"stack":["0x0"],"depth":1,"refund":0,"opName":"SLOAD"}
|
||||
{"pc":4,"op":84,"gas":"0x48456","gasCost":"0x64","memSize":0,"stack":["0x3"],"depth":1,"refund":0,"opName":"SLOAD"}
|
||||
```
|
||||
|
||||
If we try to execute it on older rules:
|
||||
```
|
||||
dir=./testdata/8 && ./evm t8n --state.fork=Istanbul --input.alloc=$dir/alloc.json --input.txs=$dir/txs.json --input.env=$dir/env.json
|
||||
INFO [01-21|23:21:51.265] rejected tx index=0 hash=d2818d..6ab3da error="tx type not supported"
|
||||
INFO [01-21|23:21:51.265] rejected tx index=1 hash=26ea00..81c01b from=0xa94f5374Fce5edBC8E2a8697C15331677e6EbF0B error="nonce too high: address 0xa94f5374Fce5edBC8E2a8697C15331677e6EbF0B, tx: 1 state: 0"
|
||||
INFO [01-21|23:21:51.265] rejected tx index=2 hash=698d01..369cee error="tx type not supported"
|
||||
$ dir=./testdata/8 && ./evm t8n --state.fork=Istanbul --input.alloc=$dir/alloc.json --input.txs=$dir/txs.json --input.env=$dir/env.json
|
||||
ERROR(10): failed signing transactions: ERROR(10): tx 0: failed to sign tx: transaction type not supported
|
||||
```
|
||||
Number `1` and `3` are not applicable, and therefore number `2` has wrong nonce.
|
||||
58
cmd/evm/testdata/9/readme.md
vendored
58
cmd/evm/testdata/9/readme.md
vendored
|
|
@ -22,35 +22,37 @@ There are two transactions, each invokes the contract above.
|
|||
|
||||
Running it yields:
|
||||
```
|
||||
$ dir=./testdata/9 && ./evm t8n --state.fork=London --input.alloc=$dir/alloc.json --input.txs=$dir/txs.json --input.env=$dir/env.json --trace && cat trace-* | grep SLOAD
|
||||
{"pc":2,"op":84,"gas":"0x48c28","gasCost":"0x834","memory":"0x","memSize":0,"stack":["0x0","0x1"],"returnStack":null,"returnD
|
||||
ata":"0x","depth":1,"refund":0,"opName":"SLOAD","error":""}
|
||||
{"pc":3,"op":84,"gas":"0x483f4","gasCost":"0x64","memory":"0x","memSize":0,"stack":["0x0","0x0"],"returnStack":null,"returnDa
|
||||
ta":"0x","depth":1,"refund":0,"opName":"SLOAD","error":""}
|
||||
{"pc":2,"op":84,"gas":"0x49cf4","gasCost":"0x834","memory":"0x","memSize":0,"stack":["0x0","0x1"],"returnStack":null,"returnD
|
||||
ata":"0x","depth":1,"refund":0,"opName":"SLOAD","error":""}
|
||||
{"pc":3,"op":84,"gas":"0x494c0","gasCost":"0x834","memory":"0x","memSize":0,"stack":["0x0","0x0"],"returnStack":null,"returnD
|
||||
ata":"0x","depth":1,"refund":0,"opName":"SLOAD","error":""}
|
||||
$ dir=./testdata/9 && ./evm t8n --state.fork=London --input.alloc=$dir/alloc.json --input.txs=$dir/txs.json --input.env=$dir/env.json --trace 2>/dev/null && cat trace-* | grep SLOAD
|
||||
{"pc":1,"op":84,"gas":"0x484be","gasCost":"0x834","memSize":0,"stack":["0x0"],"depth":1,"refund":0,"opName":"SLOAD"}
|
||||
{"pc":4,"op":84,"gas":"0x47c86","gasCost":"0x834","memSize":0,"stack":["0x3"],"depth":1,"refund":0,"opName":"SLOAD"}
|
||||
{"pc":2,"op":84,"gas":"0x48c28","gasCost":"0x834","memSize":0,"stack":["0x0","0x1"],"depth":1,"refund":0,"opName":"SLOAD"}
|
||||
{"pc":3,"op":84,"gas":"0x483f4","gasCost":"0x64","memSize":0,"stack":["0x0","0x0"],"depth":1,"refund":0,"opName":"SLOAD"}
|
||||
{"pc":1,"op":84,"gas":"0x49cf6","gasCost":"0x834","memSize":0,"stack":["0x0"],"depth":1,"refund":0,"opName":"SLOAD"}
|
||||
{"pc":4,"op":84,"gas":"0x494be","gasCost":"0x834","memSize":0,"stack":["0x3"],"depth":1,"refund":0,"opName":"SLOAD"}
|
||||
{"pc":2,"op":84,"gas":"0x49cf4","gasCost":"0x834","memSize":0,"stack":["0x0","0x1"],"depth":1,"refund":0,"opName":"SLOAD"}
|
||||
{"pc":3,"op":84,"gas":"0x494c0","gasCost":"0x834","memSize":0,"stack":["0x0","0x0"],"depth":1,"refund":0,"opName":"SLOAD"}
|
||||
{"pc":1,"op":84,"gas":"0x484be","gasCost":"0x64","memSize":0,"stack":["0x0"],"depth":1,"refund":0,"opName":"SLOAD"}
|
||||
{"pc":4,"op":84,"gas":"0x48456","gasCost":"0x64","memSize":0,"stack":["0x3"],"depth":1,"refund":0,"opName":"SLOAD"}
|
||||
```
|
||||
|
||||
We can also get the post-alloc:
|
||||
```
|
||||
$ dir=./testdata/9 && ./evm t8n --state.fork=London --input.alloc=$dir/alloc.json --input.txs=$dir/txs.json --input.env=$dir/env.json --output.alloc=stdout
|
||||
$ dir=./testdata/9 && ./evm t8n --state.fork=London --input.alloc=$dir/alloc.json --input.txs=$dir/txs.json --input.env=$dir/env.json --output.alloc=stdout 2>/dev/null
|
||||
{
|
||||
"alloc": {
|
||||
"0x000000000000000000000000000000000000aaaa": {
|
||||
"code": "0x58585454",
|
||||
"balance": "0x3",
|
||||
"nonce": "0x1"
|
||||
},
|
||||
"0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba": {
|
||||
"balance": "0x5bb10ddef6e0"
|
||||
},
|
||||
"0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b": {
|
||||
"balance": "0xff745ee8832120",
|
||||
"nonce": "0x2"
|
||||
"alloc": {
|
||||
"0x000000000000000000000000000000000000aaaa": {
|
||||
"code": "0x58585454",
|
||||
"balance": "0x3",
|
||||
"nonce": "0x1"
|
||||
},
|
||||
"0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba": {
|
||||
"balance": "0x5bb10ddef6e0"
|
||||
},
|
||||
"0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b": {
|
||||
"balance": "0xff745ee8832120",
|
||||
"nonce": "0x2"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
|
@ -65,10 +67,12 @@ by feeding it presigned transactions, located in `txs_signed.json`.
|
|||
|
||||
```
|
||||
dir=./testdata/9 && ./evm t8n --state.fork=Berlin --input.alloc=$dir/alloc.json --input.txs=$dir/txs_signed.json --input.env=$dir/env.json
|
||||
INFO [05-07|12:28:42.072] rejected tx index=0 hash=b4821e..536819 error="transaction type not supported"
|
||||
INFO [05-07|12:28:42.072] rejected tx index=1 hash=a9c6c6..fa4036 from=0xa94f5374Fce5edBC8E2a8697C15331677e6EbF0B error="nonce too high: address 0xa94f5374Fce5edBC8E2a8697C15331677e6EbF0B, tx: 1 state: 0"
|
||||
INFO [05-07|12:28:42.073] Wrote file file=alloc.json
|
||||
INFO [05-07|12:28:42.073] Wrote file file=result.json
|
||||
WARN [03-09|11:06:22.065] rejected tx index=0 hash=334e09..f8dce5 error="transaction type not supported"
|
||||
INFO [03-09|11:06:22.066] rejected tx index=1 hash=a9c6c6..fa4036 from=0xa94f5374Fce5edBC8E2a8697C15331677e6EbF0B error="nonce too high: address 0xa94f5374Fce5edBC8E2a8697C15331677e6EbF0B, tx: 1 state: 0"
|
||||
INFO [03-09|11:06:22.066] Trie dumping started root=6eebe9..a0fda5
|
||||
INFO [03-09|11:06:22.066] Trie dumping complete accounts=2 elapsed="55.844µs"
|
||||
INFO [03-09|11:06:22.066] Wrote file file=alloc.json
|
||||
INFO [03-09|11:06:22.066] Wrote file file=result.json
|
||||
```
|
||||
|
||||
Number `0` is not applicable, and therefore number `1` has wrong nonce, and both are rejected.
|
||||
|
|
|
|||
37
cmd/evm/testdata/9/txs_signed.json
vendored
Normal file
37
cmd/evm/testdata/9/txs_signed.json
vendored
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
[
|
||||
{
|
||||
"gas": "0x4ef00",
|
||||
"maxFeePerGas": "0x2",
|
||||
"maxPriorityFeePerGas": "0x12A05F200",
|
||||
"chainId": "0x1",
|
||||
"input": "0x",
|
||||
"nonce": "0x0",
|
||||
"to": "0x000000000000000000000000000000000000aaaa",
|
||||
"value": "0x0",
|
||||
"type" : "0x2",
|
||||
"accessList": [
|
||||
{"address": "0x000000000000000000000000000000000000aaaa",
|
||||
"storageKeys": [
|
||||
"0x0000000000000000000000000000000000000000000000000000000000000000"
|
||||
]
|
||||
}
|
||||
],
|
||||
"v": "0x1",
|
||||
"r": "0xd77c8ff989789b5d9d99254cbae2e2996dc7e6215cba4d55254c14e6d6b9f314",
|
||||
"s": "0x5cc021481e7e6bb444bbb87ab32071e8fd0a8d1e125c7bb352d2879bd7ff5c0a",
|
||||
"secretKey": "0x45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8"
|
||||
},
|
||||
{
|
||||
"gas": "0x4ef00",
|
||||
"gasPrice": "0x12A05F200",
|
||||
"chainId": "0x1",
|
||||
"input": "0x",
|
||||
"nonce": "0x1",
|
||||
"to": "0x000000000000000000000000000000000000aaaa",
|
||||
"value": "0x0",
|
||||
"v": "0x25",
|
||||
"r": "0xbee5ec9f6650020266bf3455a852eece2b073a2fa918c4d1836a1af69c2aa50c",
|
||||
"s": "0x556c897a58dbc007a6b09814e1fba7502adb76effd2146da4365816926f387ce",
|
||||
"secretKey": "0x45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8"
|
||||
}
|
||||
]
|
||||
|
|
@ -694,41 +694,19 @@ func showMetaData(ctx *cli.Context) error {
|
|||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Error accessing ancients: %v", err)
|
||||
}
|
||||
pp := func(val *uint64) string {
|
||||
if val == nil {
|
||||
return "<nil>"
|
||||
}
|
||||
return fmt.Sprintf("%d (%#x)", *val, *val)
|
||||
}
|
||||
data := [][]string{
|
||||
{"databaseVersion", pp(rawdb.ReadDatabaseVersion(db))},
|
||||
{"headBlockHash", fmt.Sprintf("%v", rawdb.ReadHeadBlockHash(db))},
|
||||
{"headFastBlockHash", fmt.Sprintf("%v", rawdb.ReadHeadFastBlockHash(db))},
|
||||
{"headHeaderHash", fmt.Sprintf("%v", rawdb.ReadHeadHeaderHash(db))}}
|
||||
data := rawdb.ReadChainMetadata(db)
|
||||
data = append(data, []string{"frozen", fmt.Sprintf("%d items", ancients)})
|
||||
data = append(data, []string{"snapshotGenerator", snapshot.ParseGeneratorStatus(rawdb.ReadSnapshotGenerator(db))})
|
||||
if b := rawdb.ReadHeadBlock(db); b != nil {
|
||||
data = append(data, []string{"headBlock.Hash", fmt.Sprintf("%v", b.Hash())})
|
||||
data = append(data, []string{"headBlock.Root", fmt.Sprintf("%v", b.Root())})
|
||||
data = append(data, []string{"headBlock.Number", fmt.Sprintf("%d (%#x)", b.Number(), b.Number())})
|
||||
}
|
||||
if b := rawdb.ReadSkeletonSyncStatus(db); b != nil {
|
||||
data = append(data, []string{"SkeletonSyncStatus", string(b)})
|
||||
}
|
||||
if h := rawdb.ReadHeadHeader(db); h != nil {
|
||||
data = append(data, []string{"headHeader.Hash", fmt.Sprintf("%v", h.Hash())})
|
||||
data = append(data, []string{"headHeader.Root", fmt.Sprintf("%v", h.Root)})
|
||||
data = append(data, []string{"headHeader.Number", fmt.Sprintf("%d (%#x)", h.Number, h.Number)})
|
||||
}
|
||||
data = append(data, [][]string{{"frozen", fmt.Sprintf("%d items", ancients)},
|
||||
{"lastPivotNumber", pp(rawdb.ReadLastPivotNumber(db))},
|
||||
{"len(snapshotSyncStatus)", fmt.Sprintf("%d bytes", len(rawdb.ReadSnapshotSyncStatus(db)))},
|
||||
{"snapshotGenerator", snapshot.ParseGeneratorStatus(rawdb.ReadSnapshotGenerator(db))},
|
||||
{"snapshotDisabled", fmt.Sprintf("%v", rawdb.ReadSnapshotDisabled(db))},
|
||||
{"snapshotJournal", fmt.Sprintf("%d bytes", len(rawdb.ReadSnapshotJournal(db)))},
|
||||
{"snapshotRecoveryNumber", pp(rawdb.ReadSnapshotRecoveryNumber(db))},
|
||||
{"snapshotRoot", fmt.Sprintf("%v", rawdb.ReadSnapshotRoot(db))},
|
||||
{"txIndexTail", pp(rawdb.ReadTxIndexTail(db))},
|
||||
{"fastTxLookupLimit", pp(rawdb.ReadFastTxLookupLimit(db))},
|
||||
}...)
|
||||
table := tablewriter.NewWriter(os.Stdout)
|
||||
table.SetHeader([]string{"Field", "Value"})
|
||||
table.AppendBulk(data)
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -156,6 +156,11 @@ func (b *BlockGen) Number() *big.Int {
|
|||
return new(big.Int).Set(b.header.Number)
|
||||
}
|
||||
|
||||
// Timestamp returns the timestamp of the block being generated.
|
||||
func (b *BlockGen) Timestamp() uint64 {
|
||||
return b.header.Time
|
||||
}
|
||||
|
||||
// BaseFee returns the EIP-1559 base fee of the block being generated.
|
||||
func (b *BlockGen) BaseFee() *big.Int {
|
||||
return new(big.Int).Set(b.header.BaseFee)
|
||||
|
|
|
|||
|
|
@ -70,10 +70,10 @@ func NewEVMBlockContext(header *types.Header, chain ChainContext, author *common
|
|||
}
|
||||
|
||||
// NewEVMTxContext creates a new transaction context for a single transaction.
|
||||
func NewEVMTxContext(msg Message) vm.TxContext {
|
||||
func NewEVMTxContext(msg *Message) vm.TxContext {
|
||||
return vm.TxContext{
|
||||
Origin: msg.From(),
|
||||
GasPrice: new(big.Int).Set(msg.GasPrice()),
|
||||
Origin: msg.From,
|
||||
GasPrice: new(big.Int).Set(msg.GasPrice),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -308,7 +308,7 @@ func TestValidation(t *testing.T) {
|
|||
|
||||
// Local is mainnet Gray Glacier, and isn't aware of more forks. Remote announces Gray Glacier +
|
||||
// 0xffffffff. Local needs software update, reject.
|
||||
{×tampedConfig, 15050000, 0, ID{Hash: checksumToBytes(checksumUpdate(0xf0afd0e3, math.MaxUint64)), Next: 0}, ErrLocalIncompatibleOrStale},
|
||||
{params.MainnetChainConfig, 15050000, 0, ID{Hash: checksumToBytes(checksumUpdate(0xf0afd0e3, math.MaxUint64)), Next: 0}, ErrLocalIncompatibleOrStale},
|
||||
|
||||
// Local is mainnet Gray Glacier, and is aware of Shanghai. Remote announces Shanghai +
|
||||
// 0xffffffff. Local needs software update, reject.
|
||||
|
|
|
|||
|
|
@ -202,6 +202,7 @@ func NewDatabaseWithFreezer(db ethdb.KeyValueStore, ancient string, namespace st
|
|||
// Create the idle freezer instance
|
||||
frdb, err := newChainFreezer(resolveChainFreezerDir(ancient), namespace, readonly)
|
||||
if err != nil {
|
||||
printChainMetadata(db)
|
||||
return nil, err
|
||||
}
|
||||
// Since the freezer can be stored separately from the user's key-value database,
|
||||
|
|
@ -234,8 +235,10 @@ func NewDatabaseWithFreezer(db ethdb.KeyValueStore, ancient string, namespace st
|
|||
// the freezer and the key-value store.
|
||||
frgenesis, err := frdb.Ancient(ChainFreezerHashTable, 0)
|
||||
if err != nil {
|
||||
printChainMetadata(db)
|
||||
return nil, fmt.Errorf("failed to retrieve genesis from ancient %v", err)
|
||||
} else if !bytes.Equal(kvgenesis, frgenesis) {
|
||||
printChainMetadata(db)
|
||||
return nil, fmt.Errorf("genesis mismatch: %#x (leveldb) != %#x (ancients)", kvgenesis, frgenesis)
|
||||
}
|
||||
// Key-value store and freezer belong to the same network. Ensure that they
|
||||
|
|
@ -243,8 +246,19 @@ func NewDatabaseWithFreezer(db ethdb.KeyValueStore, ancient string, namespace st
|
|||
if kvhash, _ := db.Get(headerHashKey(frozen)); len(kvhash) == 0 {
|
||||
// Subsequent header after the freezer limit is missing from the database.
|
||||
// Reject startup if the database has a more recent head.
|
||||
if ldbNum := *ReadHeaderNumber(db, ReadHeadHeaderHash(db)); ldbNum > frozen-1 {
|
||||
return nil, fmt.Errorf("gap in the chain between ancients (#%d) and leveldb (#%d) ", frozen, ldbNum)
|
||||
if head := *ReadHeaderNumber(db, ReadHeadHeaderHash(db)); head > frozen-1 {
|
||||
// Find the smallest block stored in the key-value store
|
||||
// in range of [frozen, head]
|
||||
var number uint64
|
||||
for number = frozen; number <= head; number++ {
|
||||
if present, _ := db.Has(headerHashKey(number)); present {
|
||||
break
|
||||
}
|
||||
}
|
||||
// We are about to exit on error. Print database metdata beore exiting
|
||||
printChainMetadata(db)
|
||||
return nil, fmt.Errorf("gap in the chain between ancients [0 - #%d] and leveldb [#%d - #%d] ",
|
||||
frozen-1, number, head)
|
||||
}
|
||||
// Database contains only older data than the freezer, this happens if the
|
||||
// state was wiped and reinited from an existing freezer.
|
||||
|
|
@ -261,6 +275,7 @@ func NewDatabaseWithFreezer(db ethdb.KeyValueStore, ancient string, namespace st
|
|||
// Key-value store contains more data than the genesis block, make sure we
|
||||
// didn't freeze anything yet.
|
||||
if kvblob, _ := db.Get(headerHashKey(1)); len(kvblob) == 0 {
|
||||
printChainMetadata(db)
|
||||
return nil, errors.New("ancient chain segments already extracted, please set --datadir.ancient to the correct path")
|
||||
}
|
||||
// Block #1 is still in the database, we're allowed to init a new freezer
|
||||
|
|
@ -583,3 +598,42 @@ func InspectDatabase(db ethdb.Database, keyPrefix, keyStart []byte) error {
|
|||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// printChainMetadata prints out chain metadata to stderr.
|
||||
func printChainMetadata(db ethdb.KeyValueStore) {
|
||||
fmt.Fprintf(os.Stderr, "Chain metadata\n")
|
||||
for _, v := range ReadChainMetadata(db) {
|
||||
fmt.Fprintf(os.Stderr, " %s\n", strings.Join(v, ": "))
|
||||
}
|
||||
fmt.Fprintf(os.Stderr, "\n\n")
|
||||
}
|
||||
|
||||
// ReadChainMetadata returns a set of key/value pairs that contains informatin
|
||||
// about the database chain status. This can be used for diagnostic purposes
|
||||
// when investigating the state of the node.
|
||||
func ReadChainMetadata(db ethdb.KeyValueStore) [][]string {
|
||||
pp := func(val *uint64) string {
|
||||
if val == nil {
|
||||
return "<nil>"
|
||||
}
|
||||
return fmt.Sprintf("%d (%#x)", *val, *val)
|
||||
}
|
||||
data := [][]string{
|
||||
{"databaseVersion", pp(ReadDatabaseVersion(db))},
|
||||
{"headBlockHash", fmt.Sprintf("%v", ReadHeadBlockHash(db))},
|
||||
{"headFastBlockHash", fmt.Sprintf("%v", ReadHeadFastBlockHash(db))},
|
||||
{"headHeaderHash", fmt.Sprintf("%v", ReadHeadHeaderHash(db))},
|
||||
{"lastPivotNumber", pp(ReadLastPivotNumber(db))},
|
||||
{"len(snapshotSyncStatus)", fmt.Sprintf("%d bytes", len(ReadSnapshotSyncStatus(db)))},
|
||||
{"snapshotDisabled", fmt.Sprintf("%v", ReadSnapshotDisabled(db))},
|
||||
{"snapshotJournal", fmt.Sprintf("%d bytes", len(ReadSnapshotJournal(db)))},
|
||||
{"snapshotRecoveryNumber", pp(ReadSnapshotRecoveryNumber(db))},
|
||||
{"snapshotRoot", fmt.Sprintf("%v", ReadSnapshotRoot(db))},
|
||||
{"txIndexTail", pp(ReadTxIndexTail(db))},
|
||||
{"fastTxLookupLimit", pp(ReadFastTxLookupLimit(db))},
|
||||
}
|
||||
if b := ReadSkeletonSyncStatus(db); b != nil {
|
||||
data = append(data, []string{"SkeletonSyncStatus", string(b)})
|
||||
}
|
||||
return data
|
||||
}
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ func (p *statePrefetcher) Prefetch(block *types.Block, statedb *state.StateDB, c
|
|||
return
|
||||
}
|
||||
// Convert the transaction into an executable message and pre-cache its sender
|
||||
msg, err := tx.AsMessage(signer, header.BaseFee)
|
||||
msg, err := TransactionToMessage(tx, signer, header.BaseFee)
|
||||
if err != nil {
|
||||
return // Also invalid block, bail out
|
||||
}
|
||||
|
|
@ -85,7 +85,7 @@ 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 *Message, config *params.ChainConfig, gaspool *GasPool, statedb *state.StateDB, header *types.Header, evm *vm.EVM) error {
|
||||
// Update the evm with the new transaction context.
|
||||
evm.Reset(NewEVMTxContext(msg), statedb)
|
||||
// Add addresses to access list if applicable
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg
|
|||
cfg.Debug = true
|
||||
}
|
||||
vmenv := vm.NewEVM(blockContext, vm.TxContext{}, statedb, p.config, cfg)
|
||||
msg, err := tx.AsMessage(types.MakeSigner(p.config, header.Number), header.BaseFee)
|
||||
msg, err := TransactionToMessage(tx, 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)
|
||||
}
|
||||
|
|
@ -121,7 +121,7 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg
|
|||
return receipts, allLogs, *usedGas, nil
|
||||
}
|
||||
|
||||
func applyTransaction(msg types.Message, config *params.ChainConfig, 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 *Message, config *params.ChainConfig, gp *GasPool, statedb *state.StateDB, blockNumber *big.Int, blockHash common.Hash, tx *types.Transaction, usedGas *uint64, evm *vm.EVM) (*types.Receipt, error) {
|
||||
// Create a new context to be used in the EVM environment.
|
||||
txContext := NewEVMTxContext(msg)
|
||||
evm.Reset(txContext, statedb)
|
||||
|
|
@ -153,7 +153,7 @@ func applyTransaction(msg types.Message, config *params.ChainConfig, gp *GasPool
|
|||
receipt.GasUsed = result.UsedGas
|
||||
|
||||
// If the transaction created a contract, store the creation address in the receipt.
|
||||
if msg.To() == nil {
|
||||
if msg.To == nil {
|
||||
receipt.ContractAddress = crypto.CreateAddress(evm.TxContext.Origin, tx.Nonce())
|
||||
}
|
||||
|
||||
|
|
@ -171,7 +171,7 @@ func applyTransaction(msg types.Message, config *params.ChainConfig, gp *GasPool
|
|||
// 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) {
|
||||
msg, err := tx.AsMessage(types.MakeSigner(config, header.Number), header.BaseFee)
|
||||
msg, err := TransactionToMessage(tx, types.MakeSigner(config, header.Number), header.BaseFee)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,10 +25,10 @@ import (
|
|||
cmath "github.com/ethereum/go-ethereum/common/math"
|
||||
"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/params"
|
||||
)
|
||||
|
||||
<<<<<<< HEAD
|
||||
var emptyCodeHash = crypto.Keccak256Hash(nil)
|
||||
|
||||
// StateTransition represents a state transition.
|
||||
|
|
@ -85,6 +85,8 @@ type Message interface {
|
|||
AccessList() types.AccessList
|
||||
}
|
||||
|
||||
=======
|
||||
>>>>>>> v1.11.4
|
||||
// ExecutionResult includes all output after executing given evm
|
||||
// message no matter the execution itself is successful or not.
|
||||
type ExecutionResult struct {
|
||||
|
|
@ -179,19 +181,47 @@ func toWordSize(size uint64) uint64 {
|
|||
return (size + 31) / 32
|
||||
}
|
||||
|
||||
// NewStateTransition initialises and returns a new state transition object.
|
||||
func NewStateTransition(evm *vm.EVM, msg Message, gp *GasPool) *StateTransition {
|
||||
return &StateTransition{
|
||||
gp: gp,
|
||||
evm: evm,
|
||||
msg: msg,
|
||||
gasPrice: msg.GasPrice(),
|
||||
gasFeeCap: msg.GasFeeCap(),
|
||||
gasTipCap: msg.GasTipCap(),
|
||||
value: msg.Value(),
|
||||
data: msg.Data(),
|
||||
state: evm.StateDB,
|
||||
// A Message contains the data derived from a single transaction that is relevant to state
|
||||
// processing.
|
||||
type Message struct {
|
||||
To *common.Address
|
||||
From common.Address
|
||||
Nonce uint64
|
||||
Value *big.Int
|
||||
GasLimit uint64
|
||||
GasPrice *big.Int
|
||||
GasFeeCap *big.Int
|
||||
GasTipCap *big.Int
|
||||
Data []byte
|
||||
AccessList types.AccessList
|
||||
|
||||
// When SkipAccountCheckss is true, the message nonce is not checked against the
|
||||
// account nonce in state. It also disables checking that the sender is an EOA.
|
||||
// This field will be set to true for operations like RPC eth_call.
|
||||
SkipAccountChecks bool
|
||||
}
|
||||
|
||||
// TransactionToMessage converts a transaction into a Message.
|
||||
func TransactionToMessage(tx *types.Transaction, s types.Signer, baseFee *big.Int) (*Message, error) {
|
||||
msg := &Message{
|
||||
Nonce: tx.Nonce(),
|
||||
GasLimit: tx.Gas(),
|
||||
GasPrice: new(big.Int).Set(tx.GasPrice()),
|
||||
GasFeeCap: new(big.Int).Set(tx.GasFeeCap()),
|
||||
GasTipCap: new(big.Int).Set(tx.GasTipCap()),
|
||||
To: tx.To(),
|
||||
Value: tx.Value(),
|
||||
Data: tx.Data(),
|
||||
AccessList: tx.AccessList(),
|
||||
SkipAccountChecks: false,
|
||||
}
|
||||
// If baseFee provided, set gasPrice to effectiveGasPrice.
|
||||
if baseFee != nil {
|
||||
msg.GasPrice = cmath.BigMin(msg.GasPrice.Add(msg.GasTipCap, baseFee), msg.GasFeeCap)
|
||||
}
|
||||
var err error
|
||||
msg.From, err = types.Sender(s, tx)
|
||||
return msg, err
|
||||
}
|
||||
|
||||
// ApplyMessage computes the new state by applying the given message
|
||||
|
|
@ -201,94 +231,137 @@ func NewStateTransition(evm *vm.EVM, msg Message, gp *GasPool) *StateTransition
|
|||
// the gas used (which includes gas refunds) and an error if it failed. An error always
|
||||
// indicates a core error meaning that the message would always fail for that particular
|
||||
// state and would never be accepted within a block.
|
||||
func ApplyMessage(evm *vm.EVM, msg Message, gp *GasPool) (*ExecutionResult, error) {
|
||||
func ApplyMessage(evm *vm.EVM, msg *Message, gp *GasPool) (*ExecutionResult, error) {
|
||||
return NewStateTransition(evm, msg, gp).TransitionDb()
|
||||
}
|
||||
|
||||
// StateTransition represents a state transition.
|
||||
//
|
||||
// == The State Transitioning Model
|
||||
//
|
||||
// A state transition is a change made when a transaction is applied to the current world
|
||||
// state. The state transitioning model does all the necessary work to work out a valid new
|
||||
// state root.
|
||||
//
|
||||
// 1. Nonce handling
|
||||
// 2. Pre pay gas
|
||||
// 3. Create a new state object if the recipient is nil
|
||||
// 4. Value transfer
|
||||
//
|
||||
// == If contract creation ==
|
||||
//
|
||||
// 4a. Attempt to run transaction data
|
||||
// 4b. If valid, use result as code for the new state object
|
||||
//
|
||||
// == end ==
|
||||
//
|
||||
// 5. Run Script section
|
||||
// 6. Derive new state root
|
||||
type StateTransition struct {
|
||||
gp *GasPool
|
||||
msg *Message
|
||||
gasRemaining uint64
|
||||
initialGas uint64
|
||||
state vm.StateDB
|
||||
evm *vm.EVM
|
||||
}
|
||||
|
||||
// NewStateTransition initialises and returns a new state transition object.
|
||||
func NewStateTransition(evm *vm.EVM, msg *Message, gp *GasPool) *StateTransition {
|
||||
return &StateTransition{
|
||||
gp: gp,
|
||||
evm: evm,
|
||||
msg: msg,
|
||||
state: evm.StateDB,
|
||||
}
|
||||
}
|
||||
|
||||
// to returns the recipient of the message.
|
||||
func (st *StateTransition) to() common.Address {
|
||||
if st.msg == nil || st.msg.To() == nil /* contract creation */ {
|
||||
if st.msg == nil || st.msg.To == nil /* contract creation */ {
|
||||
return common.Address{}
|
||||
}
|
||||
return *st.msg.To()
|
||||
return *st.msg.To
|
||||
}
|
||||
|
||||
func (st *StateTransition) buyGas() error {
|
||||
mgval := new(big.Int).SetUint64(st.msg.Gas())
|
||||
mgval = mgval.Mul(mgval, st.gasPrice)
|
||||
mgval := new(big.Int).SetUint64(st.msg.GasLimit)
|
||||
mgval = mgval.Mul(mgval, st.msg.GasPrice)
|
||||
if st.evm.Config.PreExec {
|
||||
mgval = big.NewInt(0)
|
||||
}
|
||||
balanceCheck := mgval
|
||||
if st.gasFeeCap != nil {
|
||||
balanceCheck = new(big.Int).SetUint64(st.msg.Gas())
|
||||
balanceCheck = balanceCheck.Mul(balanceCheck, st.gasFeeCap)
|
||||
if st.msg.GasFeeCap != nil {
|
||||
balanceCheck = new(big.Int).SetUint64(st.msg.GasLimit)
|
||||
balanceCheck = balanceCheck.Mul(balanceCheck, st.msg.GasFeeCap)
|
||||
if st.evm.Config.PreExec {
|
||||
balanceCheck = big.NewInt(0)
|
||||
}
|
||||
balanceCheck.Add(balanceCheck, st.value)
|
||||
balanceCheck.Add(balanceCheck, st.msg.Value)
|
||||
}
|
||||
if have, want := st.state.GetBalance(st.msg.From()), balanceCheck; have.Cmp(want) < 0 {
|
||||
return fmt.Errorf("%w: address %v have %v want %v", ErrInsufficientFunds, st.msg.From().Hex(), have, want)
|
||||
if have, want := st.state.GetBalance(st.msg.From), balanceCheck; have.Cmp(want) < 0 {
|
||||
return fmt.Errorf("%w: address %v have %v want %v", ErrInsufficientFunds, st.msg.From.Hex(), have, want)
|
||||
}
|
||||
if err := st.gp.SubGas(st.msg.Gas()); err != nil {
|
||||
if err := st.gp.SubGas(st.msg.GasLimit); err != nil {
|
||||
return err
|
||||
}
|
||||
st.gas += st.msg.Gas()
|
||||
st.gasRemaining += st.msg.GasLimit
|
||||
|
||||
st.initialGas = st.msg.Gas()
|
||||
st.state.SubBalance(st.msg.From(), mgval)
|
||||
st.initialGas = st.msg.GasLimit
|
||||
st.state.SubBalance(st.msg.From, mgval)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (st *StateTransition) preCheck() error {
|
||||
// Only check transactions that are not fake
|
||||
if !st.msg.IsFake() {
|
||||
msg := st.msg
|
||||
if !msg.SkipAccountChecks {
|
||||
// Make sure this transaction's nonce is correct.
|
||||
stNonce := st.state.GetNonce(st.msg.From())
|
||||
if msgNonce := st.msg.Nonce(); stNonce < msgNonce {
|
||||
stNonce := st.state.GetNonce(msg.From)
|
||||
if msgNonce := msg.Nonce; stNonce < msgNonce {
|
||||
return fmt.Errorf("%w: address %v, tx: %d state: %d", ErrNonceTooHigh,
|
||||
st.msg.From().Hex(), msgNonce, stNonce)
|
||||
msg.From.Hex(), msgNonce, stNonce)
|
||||
} else if stNonce > msgNonce {
|
||||
return fmt.Errorf("%w: address %v, tx: %d state: %d", ErrNonceTooLow,
|
||||
st.msg.From().Hex(), msgNonce, stNonce)
|
||||
msg.From.Hex(), msgNonce, stNonce)
|
||||
} else if stNonce+1 < stNonce {
|
||||
return fmt.Errorf("%w: address %v, nonce: %d", ErrNonceMax,
|
||||
st.msg.From().Hex(), stNonce)
|
||||
msg.From.Hex(), stNonce)
|
||||
}
|
||||
|
||||
// pre exec tx not check sender
|
||||
// pre exec for gnosis safe address
|
||||
if !st.msg.IsPre() {
|
||||
// Make sure the sender is an EOA
|
||||
if codeHash := st.state.GetCodeHash(st.msg.From()); codeHash != emptyCodeHash && codeHash != (common.Hash{}) {
|
||||
return fmt.Errorf("%w: address %v, codehash: %s", ErrSenderNoEOA,
|
||||
st.msg.From().Hex(), codeHash)
|
||||
}
|
||||
// Make sure the sender is an EOA
|
||||
codeHash := st.state.GetCodeHash(msg.From)
|
||||
if codeHash != (common.Hash{}) && codeHash != types.EmptyCodeHash {
|
||||
return fmt.Errorf("%w: address %v, codehash: %s", ErrSenderNoEOA,
|
||||
msg.From.Hex(), codeHash)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Make sure that transaction gasFeeCap is greater than the baseFee (post london)
|
||||
if st.evm.ChainConfig().IsLondon(st.evm.Context.BlockNumber) && !st.msg.IsPre() {
|
||||
// Skip the checks if gas fields are zero and baseFee was explicitly disabled (eth_call)
|
||||
if !st.evm.Config.NoBaseFee || st.gasFeeCap.BitLen() > 0 || st.gasTipCap.BitLen() > 0 {
|
||||
if l := st.gasFeeCap.BitLen(); l > 256 {
|
||||
if !st.evm.Config.NoBaseFee || msg.GasFeeCap.BitLen() > 0 || msg.GasTipCap.BitLen() > 0 {
|
||||
if l := msg.GasFeeCap.BitLen(); l > 256 {
|
||||
return fmt.Errorf("%w: address %v, maxFeePerGas bit length: %d", ErrFeeCapVeryHigh,
|
||||
st.msg.From().Hex(), l)
|
||||
msg.From.Hex(), l)
|
||||
}
|
||||
if l := st.gasTipCap.BitLen(); l > 256 {
|
||||
if l := msg.GasTipCap.BitLen(); l > 256 {
|
||||
return fmt.Errorf("%w: address %v, maxPriorityFeePerGas bit length: %d", ErrTipVeryHigh,
|
||||
st.msg.From().Hex(), l)
|
||||
msg.From.Hex(), l)
|
||||
}
|
||||
if st.gasFeeCap.Cmp(st.gasTipCap) < 0 {
|
||||
if msg.GasFeeCap.Cmp(msg.GasTipCap) < 0 {
|
||||
return fmt.Errorf("%w: address %v, maxPriorityFeePerGas: %s, maxFeePerGas: %s", ErrTipAboveFeeCap,
|
||||
st.msg.From().Hex(), st.gasTipCap, st.gasFeeCap)
|
||||
msg.From.Hex(), msg.GasTipCap, msg.GasFeeCap)
|
||||
}
|
||||
// This will panic if baseFee is nil, but basefee presence is verified
|
||||
// as part of header validation.
|
||||
if st.gasFeeCap.Cmp(st.evm.Context.BaseFee) < 0 {
|
||||
if msg.GasFeeCap.Cmp(st.evm.Context.BaseFee) < 0 {
|
||||
return fmt.Errorf("%w: address %v, maxFeePerGas: %s baseFee: %s", ErrFeeCapTooLow,
|
||||
st.msg.From().Hex(), st.gasFeeCap, st.evm.Context.BaseFee)
|
||||
msg.From.Hex(), msg.GasFeeCap, st.evm.Context.BaseFee)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -324,52 +397,52 @@ func (st *StateTransition) TransitionDb() (*ExecutionResult, error) {
|
|||
if st.evm.Config.Debug {
|
||||
st.evm.Config.Tracer.CaptureTxStart(st.initialGas)
|
||||
defer func() {
|
||||
st.evm.Config.Tracer.CaptureTxEnd(st.gas)
|
||||
st.evm.Config.Tracer.CaptureTxEnd(st.gasRemaining)
|
||||
}()
|
||||
}
|
||||
|
||||
var (
|
||||
msg = st.msg
|
||||
sender = vm.AccountRef(msg.From())
|
||||
sender = vm.AccountRef(msg.From)
|
||||
rules = st.evm.ChainConfig().Rules(st.evm.Context.BlockNumber, st.evm.Context.Random != nil, st.evm.Context.Time)
|
||||
contractCreation = msg.To() == nil
|
||||
contractCreation = msg.To == nil
|
||||
)
|
||||
|
||||
// Check clauses 4-5, subtract intrinsic gas if everything is correct
|
||||
gas, err := IntrinsicGas(st.data, st.msg.AccessList(), contractCreation, rules.IsHomestead, rules.IsIstanbul, rules.IsShanghai)
|
||||
gas, err := IntrinsicGas(msg.Data, msg.AccessList, contractCreation, rules.IsHomestead, rules.IsIstanbul, rules.IsShanghai)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if st.gas < gas {
|
||||
return nil, fmt.Errorf("%w: have %d, want %d", ErrIntrinsicGas, st.gas, gas)
|
||||
if st.gasRemaining < gas {
|
||||
return nil, fmt.Errorf("%w: have %d, want %d", ErrIntrinsicGas, st.gasRemaining, gas)
|
||||
}
|
||||
st.gas -= gas
|
||||
st.gasRemaining -= gas
|
||||
|
||||
// Check clause 6
|
||||
if msg.Value().Sign() > 0 && !st.evm.Context.CanTransfer(st.state, msg.From(), msg.Value()) {
|
||||
return nil, fmt.Errorf("%w: address %v", ErrInsufficientFundsForTransfer, msg.From().Hex())
|
||||
if msg.Value.Sign() > 0 && !st.evm.Context.CanTransfer(st.state, msg.From, msg.Value) {
|
||||
return nil, fmt.Errorf("%w: address %v", ErrInsufficientFundsForTransfer, msg.From.Hex())
|
||||
}
|
||||
|
||||
// Check whether the init code size has been exceeded.
|
||||
if rules.IsShanghai && contractCreation && len(st.data) > params.MaxInitCodeSize {
|
||||
return nil, fmt.Errorf("%w: code size %v limit %v", ErrMaxInitCodeSizeExceeded, len(st.data), params.MaxInitCodeSize)
|
||||
if rules.IsShanghai && contractCreation && len(msg.Data) > params.MaxInitCodeSize {
|
||||
return nil, fmt.Errorf("%w: code size %v limit %v", ErrMaxInitCodeSizeExceeded, len(msg.Data), params.MaxInitCodeSize)
|
||||
}
|
||||
|
||||
// Execute the preparatory steps for state transition which includes:
|
||||
// - prepare accessList(post-berlin)
|
||||
// - reset transient storage(eip 1153)
|
||||
st.state.Prepare(rules, msg.From(), st.evm.Context.Coinbase, msg.To(), vm.ActivePrecompiles(rules), msg.AccessList())
|
||||
st.state.Prepare(rules, msg.From, st.evm.Context.Coinbase, msg.To, vm.ActivePrecompiles(rules), msg.AccessList)
|
||||
|
||||
var (
|
||||
ret []byte
|
||||
vmerr error // vm errors do not effect consensus and are therefore not assigned to err
|
||||
)
|
||||
if contractCreation {
|
||||
ret, _, st.gas, vmerr = st.evm.Create(sender, st.data, st.gas, st.value)
|
||||
ret, _, st.gasRemaining, vmerr = st.evm.Create(sender, msg.Data, st.gasRemaining, msg.Value)
|
||||
} else {
|
||||
// Increment the nonce for the next transaction
|
||||
st.state.SetNonce(msg.From(), st.state.GetNonce(sender.Address())+1)
|
||||
ret, st.gas, vmerr = st.evm.Call(sender, st.to(), st.data, st.gas, st.value)
|
||||
st.state.SetNonce(msg.From, st.state.GetNonce(sender.Address())+1)
|
||||
ret, st.gasRemaining, vmerr = st.evm.Call(sender, st.to(), msg.Data, st.gasRemaining, msg.Value)
|
||||
}
|
||||
|
||||
if !rules.IsLondon {
|
||||
|
|
@ -379,12 +452,12 @@ func (st *StateTransition) TransitionDb() (*ExecutionResult, error) {
|
|||
// After EIP-3529: refunds are capped to gasUsed / 5
|
||||
st.refundGas(params.RefundQuotientEIP3529)
|
||||
}
|
||||
effectiveTip := st.gasPrice
|
||||
effectiveTip := msg.GasPrice
|
||||
if rules.IsLondon {
|
||||
effectiveTip = cmath.BigMin(st.gasTipCap, new(big.Int).Sub(st.gasFeeCap, st.evm.Context.BaseFee))
|
||||
effectiveTip = cmath.BigMin(msg.GasTipCap, new(big.Int).Sub(msg.GasFeeCap, st.evm.Context.BaseFee))
|
||||
}
|
||||
|
||||
if st.evm.Config.NoBaseFee && st.gasFeeCap.Sign() == 0 && st.gasTipCap.Sign() == 0 {
|
||||
if st.evm.Config.NoBaseFee && msg.GasFeeCap.Sign() == 0 && msg.GasTipCap.Sign() == 0 {
|
||||
// Skip fee payment when NoBaseFee is set and the fee fields
|
||||
// are 0. This avoids a negative effectiveTip being applied to
|
||||
// the coinbase when simulating calls.
|
||||
|
|
@ -407,21 +480,21 @@ func (st *StateTransition) refundGas(refundQuotient uint64) {
|
|||
if refund > st.state.GetRefund() {
|
||||
refund = st.state.GetRefund()
|
||||
}
|
||||
st.gas += refund
|
||||
st.gasRemaining += refund
|
||||
|
||||
// Return ETH for remaining gas, exchanged at the original rate.
|
||||
remaining := new(big.Int).Mul(new(big.Int).SetUint64(st.gas), st.gasPrice)
|
||||
remaining := new(big.Int).Mul(new(big.Int).SetUint64(st.gasRemaining), st.msg.GasPrice)
|
||||
if st.evm.Config.PreExec {
|
||||
remaining = new(big.Int).SetUint64(0)
|
||||
}
|
||||
st.state.AddBalance(st.msg.From(), remaining)
|
||||
st.state.AddBalance(st.msg.From, remaining)
|
||||
|
||||
// Also return remaining gas to the block gas counter so it is
|
||||
// available for the next transaction.
|
||||
st.gp.AddGas(st.gas)
|
||||
st.gp.AddGas(st.gasRemaining)
|
||||
}
|
||||
|
||||
// gasUsed returns the amount of gas used up by the state transition.
|
||||
func (st *StateTransition) gasUsed() uint64 {
|
||||
return st.initialGas - st.gas
|
||||
return st.initialGas - st.gasRemaining
|
||||
}
|
||||
|
|
|
|||
|
|
@ -254,17 +254,19 @@ type list struct {
|
|||
strict bool // Whether nonces are strictly continuous or not
|
||||
txs *sortedMap // Heap indexed sorted hash map of the transactions
|
||||
|
||||
costcap *big.Int // Price of the highest costing transaction (reset only if exceeds balance)
|
||||
gascap uint64 // Gas limit of the highest spending transaction (reset only if exceeds block limit)
|
||||
costcap *big.Int // Price of the highest costing transaction (reset only if exceeds balance)
|
||||
gascap uint64 // Gas limit of the highest spending transaction (reset only if exceeds block limit)
|
||||
totalcost *big.Int // Total cost of all transactions in the list
|
||||
}
|
||||
|
||||
// newList create a new transaction list for maintaining nonce-indexable fast,
|
||||
// gapped, sortable transaction lists.
|
||||
func newList(strict bool) *list {
|
||||
return &list{
|
||||
strict: strict,
|
||||
txs: newSortedMap(),
|
||||
costcap: new(big.Int),
|
||||
strict: strict,
|
||||
txs: newSortedMap(),
|
||||
costcap: new(big.Int),
|
||||
totalcost: new(big.Int),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -302,7 +304,11 @@ func (l *list) Add(tx *types.Transaction, priceBump uint64) (bool, *types.Transa
|
|||
if tx.GasFeeCapIntCmp(thresholdFeeCap) < 0 || tx.GasTipCapIntCmp(thresholdTip) < 0 {
|
||||
return false, nil
|
||||
}
|
||||
// Old is being replaced, subtract old cost
|
||||
l.subTotalCost([]*types.Transaction{old})
|
||||
}
|
||||
// Add new tx cost to totalcost
|
||||
l.totalcost.Add(l.totalcost, tx.Cost())
|
||||
// Otherwise overwrite the old transaction with the current one
|
||||
l.txs.Put(tx)
|
||||
if cost := tx.Cost(); l.costcap.Cmp(cost) < 0 {
|
||||
|
|
@ -318,7 +324,9 @@ func (l *list) Add(tx *types.Transaction, priceBump uint64) (bool, *types.Transa
|
|||
// provided threshold. Every removed transaction is returned for any post-removal
|
||||
// maintenance.
|
||||
func (l *list) Forward(threshold uint64) types.Transactions {
|
||||
return l.txs.Forward(threshold)
|
||||
txs := l.txs.Forward(threshold)
|
||||
l.subTotalCost(txs)
|
||||
return txs
|
||||
}
|
||||
|
||||
// Filter removes all transactions from the list with a cost or gas limit higher
|
||||
|
|
@ -357,6 +365,9 @@ func (l *list) Filter(costLimit *big.Int, gasLimit uint64) (types.Transactions,
|
|||
}
|
||||
invalids = l.txs.filter(func(tx *types.Transaction) bool { return tx.Nonce() > lowest })
|
||||
}
|
||||
// Reset total cost
|
||||
l.subTotalCost(removed)
|
||||
l.subTotalCost(invalids)
|
||||
l.txs.reheap()
|
||||
return removed, invalids
|
||||
}
|
||||
|
|
@ -364,7 +375,9 @@ func (l *list) Filter(costLimit *big.Int, gasLimit uint64) (types.Transactions,
|
|||
// Cap places a hard limit on the number of items, returning all transactions
|
||||
// exceeding that limit.
|
||||
func (l *list) Cap(threshold int) types.Transactions {
|
||||
return l.txs.Cap(threshold)
|
||||
txs := l.txs.Cap(threshold)
|
||||
l.subTotalCost(txs)
|
||||
return txs
|
||||
}
|
||||
|
||||
// Remove deletes a transaction from the maintained list, returning whether the
|
||||
|
|
@ -376,9 +389,12 @@ func (l *list) Remove(tx *types.Transaction) (bool, types.Transactions) {
|
|||
if removed := l.txs.Remove(nonce); !removed {
|
||||
return false, nil
|
||||
}
|
||||
l.subTotalCost([]*types.Transaction{tx})
|
||||
// In strict mode, filter out non-executable transactions
|
||||
if l.strict {
|
||||
return true, l.txs.Filter(func(tx *types.Transaction) bool { return tx.Nonce() > nonce })
|
||||
txs := l.txs.Filter(func(tx *types.Transaction) bool { return tx.Nonce() > nonce })
|
||||
l.subTotalCost(txs)
|
||||
return true, txs
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
|
@ -391,7 +407,9 @@ func (l *list) Remove(tx *types.Transaction) (bool, types.Transactions) {
|
|||
// prevent getting into and invalid state. This is not something that should ever
|
||||
// happen but better to be self correcting than failing!
|
||||
func (l *list) Ready(start uint64) types.Transactions {
|
||||
return l.txs.Ready(start)
|
||||
txs := l.txs.Ready(start)
|
||||
l.subTotalCost(txs)
|
||||
return txs
|
||||
}
|
||||
|
||||
// Len returns the length of the transaction list.
|
||||
|
|
@ -417,6 +435,14 @@ func (l *list) LastElement() *types.Transaction {
|
|||
return l.txs.LastElement()
|
||||
}
|
||||
|
||||
// subTotalCost subtracts the cost of the given transactions from the
|
||||
// total cost of all transactions.
|
||||
func (l *list) subTotalCost(txs []*types.Transaction) {
|
||||
for _, tx := range txs {
|
||||
l.totalcost.Sub(l.totalcost, tx.Cost())
|
||||
}
|
||||
}
|
||||
|
||||
// priceHeap is a heap.Interface implementation over transactions for retrieving
|
||||
// price-sorted transactions to discard when the pool fills up. If baseFee is set
|
||||
// then the heap is sorted based on the effective tip based on the given base fee.
|
||||
|
|
@ -561,6 +587,7 @@ func (l *pricedList) underpricedFor(h *priceHeap, tx *types.Transaction) bool {
|
|||
|
||||
// Discard finds a number of most underpriced transactions, removes them from the
|
||||
// priced list and returns them for further removal from the entire pool.
|
||||
// If noPending is set to true, we will only consider the floating list
|
||||
//
|
||||
// Note local transaction won't be considered for eviction.
|
||||
func (l *pricedList) Discard(slots int, force bool) (types.Transactions, bool) {
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
package txpool
|
||||
|
||||
import (
|
||||
"container/heap"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math"
|
||||
|
|
@ -87,6 +88,14 @@ var (
|
|||
// than some meaningful limit a user might use. This is not a consensus error
|
||||
// making the transaction invalid, rather a DOS protection.
|
||||
ErrOversizedData = errors.New("oversized data")
|
||||
|
||||
// ErrFutureReplacePending is returned if a future transaction replaces a pending
|
||||
// transaction. Future transactions should only be able to replace other future transactions.
|
||||
ErrFutureReplacePending = errors.New("future transaction tries to replace pending")
|
||||
|
||||
// ErrOverdraft is returned if a transaction would cause the senders balance to go negative
|
||||
// thus invalidating a potential large number of transactions.
|
||||
ErrOverdraft = errors.New("transaction would cause overdraft")
|
||||
)
|
||||
|
||||
var (
|
||||
|
|
@ -639,9 +648,25 @@ func (pool *TxPool) validateTx(tx *types.Transaction, local bool) error {
|
|||
}
|
||||
// Transactor should have enough funds to cover the costs
|
||||
// cost == V + GP * GL
|
||||
if pool.currentState.GetBalance(from).Cmp(tx.Cost()) < 0 {
|
||||
balance := pool.currentState.GetBalance(from)
|
||||
if balance.Cmp(tx.Cost()) < 0 {
|
||||
return core.ErrInsufficientFunds
|
||||
}
|
||||
|
||||
// Verify that replacing transactions will not result in overdraft
|
||||
list := pool.pending[from]
|
||||
if list != nil { // Sender already has pending txs
|
||||
sum := new(big.Int).Add(tx.Cost(), list.totalcost)
|
||||
if repl := list.txs.Get(tx.Nonce()); repl != nil {
|
||||
// Deduct the cost of a transaction replaced by this
|
||||
sum.Sub(sum, repl.Cost())
|
||||
}
|
||||
if balance.Cmp(sum) < 0 {
|
||||
log.Trace("Replacing transactions would overdraft", "sender", from, "balance", pool.currentState.GetBalance(from), "required", sum)
|
||||
return ErrOverdraft
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure the transaction has more gas than the basic tx fee.
|
||||
intrGas, err := core.IntrinsicGas(tx.Data(), tx.AccessList(), tx.To() == nil, true, pool.istanbul, pool.shanghai)
|
||||
if err != nil {
|
||||
|
|
@ -678,6 +703,10 @@ func (pool *TxPool) add(tx *types.Transaction, local bool) (replaced bool, err e
|
|||
invalidTxMeter.Mark(1)
|
||||
return false, err
|
||||
}
|
||||
|
||||
// already validated by this point
|
||||
from, _ := types.Sender(pool.signer, tx)
|
||||
|
||||
// If the transaction pool is full, discard underpriced transactions
|
||||
if uint64(pool.all.Slots()+numSlots(tx)) > pool.config.GlobalSlots+pool.config.GlobalQueue {
|
||||
// If the new transaction is underpriced, don't accept it
|
||||
|
|
@ -686,6 +715,7 @@ func (pool *TxPool) add(tx *types.Transaction, local bool) (replaced bool, err e
|
|||
underpricedTxMeter.Mark(1)
|
||||
return false, ErrUnderpriced
|
||||
}
|
||||
|
||||
// We're about to replace a transaction. The reorg does a more thorough
|
||||
// analysis of what to remove and how, but it runs async. We don't want to
|
||||
// do too many replacements between reorg-runs, so we cap the number of
|
||||
|
|
@ -706,17 +736,37 @@ func (pool *TxPool) add(tx *types.Transaction, local bool) (replaced bool, err e
|
|||
overflowedTxMeter.Mark(1)
|
||||
return false, ErrTxPoolOverflow
|
||||
}
|
||||
// Bump the counter of rejections-since-reorg
|
||||
pool.changesSinceReorg += len(drop)
|
||||
|
||||
// If the new transaction is a future transaction it should never churn pending transactions
|
||||
if pool.isFuture(from, tx) {
|
||||
var replacesPending bool
|
||||
for _, dropTx := range drop {
|
||||
dropSender, _ := types.Sender(pool.signer, dropTx)
|
||||
if list := pool.pending[dropSender]; list != nil && list.Overlaps(dropTx) {
|
||||
replacesPending = true
|
||||
break
|
||||
}
|
||||
}
|
||||
// Add all transactions back to the priced queue
|
||||
if replacesPending {
|
||||
for _, dropTx := range drop {
|
||||
heap.Push(&pool.priced.urgent, dropTx)
|
||||
}
|
||||
log.Trace("Discarding future transaction replacing pending tx", "hash", hash)
|
||||
return false, ErrFutureReplacePending
|
||||
}
|
||||
}
|
||||
|
||||
// Kick out the underpriced remote transactions.
|
||||
for _, tx := range drop {
|
||||
log.Trace("Discarding freshly underpriced transaction", "hash", tx.Hash(), "gasTipCap", tx.GasTipCap(), "gasFeeCap", tx.GasFeeCap())
|
||||
underpricedTxMeter.Mark(1)
|
||||
pool.removeTx(tx.Hash(), false)
|
||||
dropped := pool.removeTx(tx.Hash(), false)
|
||||
pool.changesSinceReorg += dropped
|
||||
}
|
||||
}
|
||||
|
||||
// Try to replace an existing transaction in the pending pool
|
||||
from, _ := types.Sender(pool.signer, tx) // already validated
|
||||
if list := pool.pending[from]; list != nil && list.Overlaps(tx) {
|
||||
// Nonce already pending, check if required price bump is met
|
||||
inserted, old := list.Add(tx, pool.config.PriceBump)
|
||||
|
|
@ -760,6 +810,20 @@ func (pool *TxPool) add(tx *types.Transaction, local bool) (replaced bool, err e
|
|||
return replaced, nil
|
||||
}
|
||||
|
||||
// isFuture reports whether the given transaction is immediately executable.
|
||||
func (pool *TxPool) isFuture(from common.Address, tx *types.Transaction) bool {
|
||||
list := pool.pending[from]
|
||||
if list == nil {
|
||||
return pool.pendingNonces.get(from) != tx.Nonce()
|
||||
}
|
||||
// Sender has pending transactions.
|
||||
if old := list.txs.Get(tx.Nonce()); old != nil {
|
||||
return false // It replaces a pending transaction.
|
||||
}
|
||||
// Not replacing, check if parent nonce exists in pending.
|
||||
return list.txs.Get(tx.Nonce()-1) == nil
|
||||
}
|
||||
|
||||
// enqueueTx inserts a new transaction into the non-executable transaction queue.
|
||||
//
|
||||
// Note, this method assumes the pool lock is held!
|
||||
|
|
@ -996,11 +1060,12 @@ func (pool *TxPool) Has(hash common.Hash) bool {
|
|||
|
||||
// removeTx removes a single transaction from the queue, moving all subsequent
|
||||
// transactions back to the future queue.
|
||||
func (pool *TxPool) removeTx(hash common.Hash, outofbound bool) {
|
||||
// Returns the number of transactions removed from the pending queue.
|
||||
func (pool *TxPool) removeTx(hash common.Hash, outofbound bool) int {
|
||||
// Fetch the transaction we wish to delete
|
||||
tx := pool.all.Get(hash)
|
||||
if tx == nil {
|
||||
return
|
||||
return 0
|
||||
}
|
||||
addr, _ := types.Sender(pool.signer, tx) // already validated during insertion
|
||||
|
||||
|
|
@ -1028,7 +1093,7 @@ func (pool *TxPool) removeTx(hash common.Hash, outofbound bool) {
|
|||
pool.pendingNonces.setIfLower(addr, tx.Nonce())
|
||||
// Reduce the pending counter
|
||||
pendingGauge.Dec(int64(1 + len(invalids)))
|
||||
return
|
||||
return 1 + len(invalids)
|
||||
}
|
||||
}
|
||||
// Transaction is in the future queue
|
||||
|
|
@ -1042,6 +1107,7 @@ func (pool *TxPool) removeTx(hash common.Hash, outofbound bool) {
|
|||
delete(pool.beats, addr)
|
||||
}
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// requestReset requests a pool reset to the new head block.
|
||||
|
|
|
|||
212
core/txpool/txpool2_test.go
Normal file
212
core/txpool/txpool2_test.go
Normal file
|
|
@ -0,0 +1,212 @@
|
|||
// Copyright 2023 The go-ethereum Authors
|
||||
// This file is part of the go-ethereum library.
|
||||
//
|
||||
// The go-ethereum library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// The go-ethereum library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||
package txpool
|
||||
|
||||
import (
|
||||
"crypto/ecdsa"
|
||||
"math/big"
|
||||
"testing"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/core/rawdb"
|
||||
"github.com/ethereum/go-ethereum/core/state"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/ethereum/go-ethereum/event"
|
||||
)
|
||||
|
||||
func pricedValuedTransaction(nonce uint64, value int64, gaslimit uint64, gasprice *big.Int, key *ecdsa.PrivateKey) *types.Transaction {
|
||||
tx, _ := types.SignTx(types.NewTransaction(nonce, common.Address{}, big.NewInt(value), gaslimit, gasprice, nil), types.HomesteadSigner{}, key)
|
||||
return tx
|
||||
}
|
||||
|
||||
func count(t *testing.T, pool *TxPool) (pending int, queued int) {
|
||||
t.Helper()
|
||||
pending, queued = pool.stats()
|
||||
if err := validatePoolInternals(pool); err != nil {
|
||||
t.Fatalf("pool internal state corrupted: %v", err)
|
||||
}
|
||||
return pending, queued
|
||||
}
|
||||
|
||||
func fillPool(t *testing.T, pool *TxPool) {
|
||||
t.Helper()
|
||||
// Create a number of test accounts, fund them and make transactions
|
||||
executableTxs := types.Transactions{}
|
||||
nonExecutableTxs := types.Transactions{}
|
||||
for i := 0; i < 384; i++ {
|
||||
key, _ := crypto.GenerateKey()
|
||||
pool.currentState.AddBalance(crypto.PubkeyToAddress(key.PublicKey), big.NewInt(10000000000))
|
||||
// Add executable ones
|
||||
for j := 0; j < int(pool.config.AccountSlots); j++ {
|
||||
executableTxs = append(executableTxs, pricedTransaction(uint64(j), 100000, big.NewInt(300), key))
|
||||
}
|
||||
}
|
||||
// Import the batch and verify that limits have been enforced
|
||||
pool.AddRemotesSync(executableTxs)
|
||||
pool.AddRemotesSync(nonExecutableTxs)
|
||||
pending, queued := pool.Stats()
|
||||
slots := pool.all.Slots()
|
||||
// sanity-check that the test prerequisites are ok (pending full)
|
||||
if have, want := pending, slots; have != want {
|
||||
t.Fatalf("have %d, want %d", have, want)
|
||||
}
|
||||
if have, want := queued, 0; have != want {
|
||||
t.Fatalf("have %d, want %d", have, want)
|
||||
}
|
||||
|
||||
t.Logf("pool.config: GlobalSlots=%d, GlobalQueue=%d\n", pool.config.GlobalSlots, pool.config.GlobalQueue)
|
||||
t.Logf("pending: %d queued: %d, all: %d\n", pending, queued, slots)
|
||||
}
|
||||
|
||||
// Tests that if a batch high-priced of non-executables arrive, they do not kick out
|
||||
// executable transactions
|
||||
func TestTransactionFutureAttack(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
// Create the pool to test the limit enforcement with
|
||||
statedb, _ := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
|
||||
blockchain := &testBlockChain{1000000, statedb, new(event.Feed)}
|
||||
config := testTxPoolConfig
|
||||
config.GlobalQueue = 100
|
||||
config.GlobalSlots = 100
|
||||
pool := NewTxPool(config, eip1559Config, blockchain)
|
||||
defer pool.Stop()
|
||||
fillPool(t, pool)
|
||||
pending, _ := pool.Stats()
|
||||
// Now, future transaction attack starts, let's add a bunch of expensive non-executables, and see if the pending-count drops
|
||||
{
|
||||
key, _ := crypto.GenerateKey()
|
||||
pool.currentState.AddBalance(crypto.PubkeyToAddress(key.PublicKey), big.NewInt(100000000000))
|
||||
futureTxs := types.Transactions{}
|
||||
for j := 0; j < int(pool.config.GlobalSlots+pool.config.GlobalQueue); j++ {
|
||||
futureTxs = append(futureTxs, pricedTransaction(1000+uint64(j), 100000, big.NewInt(500), key))
|
||||
}
|
||||
for i := 0; i < 5; i++ {
|
||||
pool.AddRemotesSync(futureTxs)
|
||||
newPending, newQueued := count(t, pool)
|
||||
t.Logf("pending: %d queued: %d, all: %d\n", newPending, newQueued, pool.all.Slots())
|
||||
}
|
||||
}
|
||||
newPending, _ := pool.Stats()
|
||||
// Pending should not have been touched
|
||||
if have, want := newPending, pending; have < want {
|
||||
t.Errorf("wrong pending-count, have %d, want %d (GlobalSlots: %d)",
|
||||
have, want, pool.config.GlobalSlots)
|
||||
}
|
||||
}
|
||||
|
||||
// Tests that if a batch high-priced of non-executables arrive, they do not kick out
|
||||
// executable transactions
|
||||
func TestTransactionFuture1559(t *testing.T) {
|
||||
t.Parallel()
|
||||
// Create the pool to test the pricing enforcement with
|
||||
statedb, _ := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
|
||||
blockchain := &testBlockChain{1000000, statedb, new(event.Feed)}
|
||||
pool := NewTxPool(testTxPoolConfig, eip1559Config, blockchain)
|
||||
defer pool.Stop()
|
||||
|
||||
// Create a number of test accounts, fund them and make transactions
|
||||
fillPool(t, pool)
|
||||
pending, _ := pool.Stats()
|
||||
|
||||
// Now, future transaction attack starts, let's add a bunch of expensive non-executables, and see if the pending-count drops
|
||||
{
|
||||
key, _ := crypto.GenerateKey()
|
||||
pool.currentState.AddBalance(crypto.PubkeyToAddress(key.PublicKey), big.NewInt(100000000000))
|
||||
futureTxs := types.Transactions{}
|
||||
for j := 0; j < int(pool.config.GlobalSlots+pool.config.GlobalQueue); j++ {
|
||||
futureTxs = append(futureTxs, dynamicFeeTx(1000+uint64(j), 100000, big.NewInt(200), big.NewInt(101), key))
|
||||
}
|
||||
pool.AddRemotesSync(futureTxs)
|
||||
}
|
||||
newPending, _ := pool.Stats()
|
||||
// Pending should not have been touched
|
||||
if have, want := newPending, pending; have != want {
|
||||
t.Errorf("Wrong pending-count, have %d, want %d (GlobalSlots: %d)",
|
||||
have, want, pool.config.GlobalSlots)
|
||||
}
|
||||
}
|
||||
|
||||
// Tests that if a batch of balance-overdraft txs arrive, they do not kick out
|
||||
// executable transactions
|
||||
func TestTransactionZAttack(t *testing.T) {
|
||||
t.Parallel()
|
||||
// Create the pool to test the pricing enforcement with
|
||||
statedb, _ := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
|
||||
blockchain := &testBlockChain{1000000, statedb, new(event.Feed)}
|
||||
pool := NewTxPool(testTxPoolConfig, eip1559Config, blockchain)
|
||||
defer pool.Stop()
|
||||
// Create a number of test accounts, fund them and make transactions
|
||||
fillPool(t, pool)
|
||||
|
||||
countInvalidPending := func() int {
|
||||
t.Helper()
|
||||
var ivpendingNum int
|
||||
pendingtxs, _ := pool.Content()
|
||||
for account, txs := range pendingtxs {
|
||||
cur_balance := new(big.Int).Set(pool.currentState.GetBalance(account))
|
||||
for _, tx := range txs {
|
||||
if cur_balance.Cmp(tx.Value()) <= 0 {
|
||||
ivpendingNum++
|
||||
} else {
|
||||
cur_balance.Sub(cur_balance, tx.Value())
|
||||
}
|
||||
}
|
||||
}
|
||||
if err := validatePoolInternals(pool); err != nil {
|
||||
t.Fatalf("pool internal state corrupted: %v", err)
|
||||
}
|
||||
return ivpendingNum
|
||||
}
|
||||
ivPending := countInvalidPending()
|
||||
t.Logf("invalid pending: %d\n", ivPending)
|
||||
|
||||
// Now, DETER-Z attack starts, let's add a bunch of expensive non-executables (from N accounts) along with balance-overdraft txs (from one account), and see if the pending-count drops
|
||||
for j := 0; j < int(pool.config.GlobalQueue); j++ {
|
||||
futureTxs := types.Transactions{}
|
||||
key, _ := crypto.GenerateKey()
|
||||
pool.currentState.AddBalance(crypto.PubkeyToAddress(key.PublicKey), big.NewInt(100000000000))
|
||||
futureTxs = append(futureTxs, pricedTransaction(1000+uint64(j), 21000, big.NewInt(500), key))
|
||||
pool.AddRemotesSync(futureTxs)
|
||||
}
|
||||
|
||||
overDraftTxs := types.Transactions{}
|
||||
{
|
||||
key, _ := crypto.GenerateKey()
|
||||
pool.currentState.AddBalance(crypto.PubkeyToAddress(key.PublicKey), big.NewInt(100000000000))
|
||||
for j := 0; j < int(pool.config.GlobalSlots); j++ {
|
||||
overDraftTxs = append(overDraftTxs, pricedValuedTransaction(uint64(j), 60000000000, 21000, big.NewInt(500), key))
|
||||
}
|
||||
}
|
||||
pool.AddRemotesSync(overDraftTxs)
|
||||
pool.AddRemotesSync(overDraftTxs)
|
||||
pool.AddRemotesSync(overDraftTxs)
|
||||
pool.AddRemotesSync(overDraftTxs)
|
||||
pool.AddRemotesSync(overDraftTxs)
|
||||
|
||||
newPending, newQueued := count(t, pool)
|
||||
newIvPending := countInvalidPending()
|
||||
t.Logf("pool.all.Slots(): %d\n", pool.all.Slots())
|
||||
t.Logf("pending: %d queued: %d, all: %d\n", newPending, newQueued, pool.all.Slots())
|
||||
t.Logf("invalid pending: %d\n", newIvPending)
|
||||
|
||||
// Pending should not have been touched
|
||||
if newIvPending != ivPending {
|
||||
t.Errorf("Wrong invalid pending-count, have %d, want %d (GlobalSlots: %d, queued: %d)",
|
||||
newIvPending, ivPending, pool.config.GlobalSlots, newQueued)
|
||||
}
|
||||
}
|
||||
|
|
@ -158,6 +158,9 @@ func validatePoolInternals(pool *TxPool) error {
|
|||
if nonce := pool.pendingNonces.get(addr); nonce != last+1 {
|
||||
return fmt.Errorf("pending nonce mismatch: have %v, want %v", nonce, last+1)
|
||||
}
|
||||
if txs.totalcost.Cmp(common.Big0) < 0 {
|
||||
return fmt.Errorf("totalcost went negative: %v", txs.totalcost)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
@ -1105,7 +1108,7 @@ func TestPendingLimiting(t *testing.T) {
|
|||
defer pool.Stop()
|
||||
|
||||
account := crypto.PubkeyToAddress(key.PublicKey)
|
||||
testAddBalance(pool, account, big.NewInt(1000000))
|
||||
testAddBalance(pool, account, big.NewInt(1000000000000))
|
||||
|
||||
// Keep track of transaction events to ensure all executables get announced
|
||||
events := make(chan core.NewTxsEvent, testTxPoolConfig.AccountQueue+5)
|
||||
|
|
@ -1584,7 +1587,7 @@ func TestRepricingKeepsLocals(t *testing.T) {
|
|||
keys := make([]*ecdsa.PrivateKey, 3)
|
||||
for i := 0; i < len(keys); i++ {
|
||||
keys[i], _ = crypto.GenerateKey()
|
||||
testAddBalance(pool, crypto.PubkeyToAddress(keys[i].PublicKey), big.NewInt(1000*1000000))
|
||||
testAddBalance(pool, crypto.PubkeyToAddress(keys[i].PublicKey), big.NewInt(100000*1000000))
|
||||
}
|
||||
// Create transaction (both pending and queued) with a linearly growing gasprice
|
||||
for i := uint64(0); i < 500; i++ {
|
||||
|
|
@ -1663,7 +1666,7 @@ func TestUnderpricing(t *testing.T) {
|
|||
defer sub.Unsubscribe()
|
||||
|
||||
// Create a number of test accounts and fund them
|
||||
keys := make([]*ecdsa.PrivateKey, 4)
|
||||
keys := make([]*ecdsa.PrivateKey, 5)
|
||||
for i := 0; i < len(keys); i++ {
|
||||
keys[i], _ = crypto.GenerateKey()
|
||||
testAddBalance(pool, crypto.PubkeyToAddress(keys[i].PublicKey), big.NewInt(1000000))
|
||||
|
|
@ -1699,6 +1702,10 @@ func TestUnderpricing(t *testing.T) {
|
|||
if err := pool.AddRemote(pricedTransaction(0, 100000, big.NewInt(1), keys[1])); err != ErrUnderpriced {
|
||||
t.Fatalf("adding underpriced pending transaction error mismatch: have %v, want %v", err, ErrUnderpriced)
|
||||
}
|
||||
// Replace a future transaction with a future transaction
|
||||
if err := pool.AddRemote(pricedTransaction(1, 100000, big.NewInt(2), keys[1])); err != nil { // +K1:1 => -K1:1 => Pend K0:0, K0:1, K2:0; Que K1:1
|
||||
t.Fatalf("failed to add well priced transaction: %v", err)
|
||||
}
|
||||
// Ensure that adding high priced transactions drops cheap ones, but not own
|
||||
if err := pool.AddRemote(pricedTransaction(0, 100000, big.NewInt(3), keys[1])); err != nil { // +K1:0 => -K1:1 => Pend K0:0, K0:1, K1:0, K2:0; Que -
|
||||
t.Fatalf("failed to add well priced transaction: %v", err)
|
||||
|
|
@ -1709,6 +1716,10 @@ func TestUnderpricing(t *testing.T) {
|
|||
if err := pool.AddRemote(pricedTransaction(3, 100000, big.NewInt(5), keys[1])); err != nil { // +K1:3 => -K0:1 => Pend K1:0, K2:0; Que K1:2 K1:3
|
||||
t.Fatalf("failed to add well priced transaction: %v", err)
|
||||
}
|
||||
// Ensure that replacing a pending transaction with a future transaction fails
|
||||
if err := pool.AddRemote(pricedTransaction(5, 100000, big.NewInt(6), keys[1])); err != ErrFutureReplacePending {
|
||||
t.Fatalf("adding future replace transaction error mismatch: have %v, want %v", err, ErrFutureReplacePending)
|
||||
}
|
||||
pending, queued = pool.Stats()
|
||||
if pending != 2 {
|
||||
t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 2)
|
||||
|
|
@ -1716,7 +1727,7 @@ func TestUnderpricing(t *testing.T) {
|
|||
if queued != 2 {
|
||||
t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 2)
|
||||
}
|
||||
if err := validateEvents(events, 1); err != nil {
|
||||
if err := validateEvents(events, 2); err != nil {
|
||||
t.Fatalf("additional event firing failed: %v", err)
|
||||
}
|
||||
if err := validatePoolInternals(pool); err != nil {
|
||||
|
|
@ -1878,11 +1889,11 @@ func TestUnderpricingDynamicFee(t *testing.T) {
|
|||
t.Fatalf("failed to add well priced transaction: %v", err)
|
||||
}
|
||||
|
||||
tx = pricedTransaction(2, 100000, big.NewInt(3), keys[1])
|
||||
tx = pricedTransaction(1, 100000, big.NewInt(3), keys[1])
|
||||
if err := pool.AddRemote(tx); err != nil { // +K1:2, -K0:1 => Pend K0:0 K1:0, K2:0; Que K1:2
|
||||
t.Fatalf("failed to add well priced transaction: %v", err)
|
||||
}
|
||||
tx = dynamicFeeTx(3, 100000, big.NewInt(4), big.NewInt(1), keys[1])
|
||||
tx = dynamicFeeTx(2, 100000, big.NewInt(4), big.NewInt(1), keys[1])
|
||||
if err := pool.AddRemote(tx); err != nil { // +K1:3, -K1:0 => Pend K0:0 K2:0; Que K1:2 K1:3
|
||||
t.Fatalf("failed to add well priced transaction: %v", err)
|
||||
}
|
||||
|
|
@ -1893,7 +1904,7 @@ func TestUnderpricingDynamicFee(t *testing.T) {
|
|||
if queued != 2 {
|
||||
t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 2)
|
||||
}
|
||||
if err := validateEvents(events, 1); err != nil {
|
||||
if err := validateEvents(events, 2); err != nil {
|
||||
t.Fatalf("additional event firing failed: %v", err)
|
||||
}
|
||||
if err := validatePoolInternals(pool); err != nil {
|
||||
|
|
@ -2487,7 +2498,7 @@ func benchmarkBatchInsert(b *testing.B, size int, local bool) {
|
|||
defer pool.Stop()
|
||||
|
||||
account := crypto.PubkeyToAddress(key.PublicKey)
|
||||
testAddBalance(pool, account, big.NewInt(1000000))
|
||||
testAddBalance(pool, account, big.NewInt(1000000000000000000))
|
||||
|
||||
batches := make([]types.Transactions, b.N)
|
||||
for i := 0; i < b.N; i++ {
|
||||
|
|
|
|||
|
|
@ -589,77 +589,6 @@ func (t *TransactionsByPriceAndNonce) Pop() {
|
|||
heap.Pop(&t.heads)
|
||||
}
|
||||
|
||||
// Message is a fully derived transaction and implements core.Message
|
||||
//
|
||||
// NOTE: In a future PR this will be removed.
|
||||
type Message struct {
|
||||
to *common.Address
|
||||
from common.Address
|
||||
nonce uint64
|
||||
amount *big.Int
|
||||
gasLimit uint64
|
||||
gasPrice *big.Int
|
||||
gasFeeCap *big.Int
|
||||
gasTipCap *big.Int
|
||||
data []byte
|
||||
accessList AccessList
|
||||
isFake bool
|
||||
isPre bool
|
||||
}
|
||||
|
||||
func NewMessage(from common.Address, to *common.Address, nonce uint64, amount *big.Int, gasLimit uint64, gasPrice, gasFeeCap, gasTipCap *big.Int, data []byte, accessList AccessList, isFake bool, isPre bool) Message {
|
||||
return Message{
|
||||
from: from,
|
||||
to: to,
|
||||
nonce: nonce,
|
||||
amount: amount,
|
||||
gasLimit: gasLimit,
|
||||
gasPrice: gasPrice,
|
||||
gasFeeCap: gasFeeCap,
|
||||
gasTipCap: gasTipCap,
|
||||
data: data,
|
||||
accessList: accessList,
|
||||
isFake: isFake,
|
||||
isPre: isPre,
|
||||
}
|
||||
}
|
||||
|
||||
// AsMessage returns the transaction as a core.Message.
|
||||
func (tx *Transaction) AsMessage(s Signer, baseFee *big.Int) (Message, error) {
|
||||
msg := Message{
|
||||
nonce: tx.Nonce(),
|
||||
gasLimit: tx.Gas(),
|
||||
gasPrice: new(big.Int).Set(tx.GasPrice()),
|
||||
gasFeeCap: new(big.Int).Set(tx.GasFeeCap()),
|
||||
gasTipCap: new(big.Int).Set(tx.GasTipCap()),
|
||||
to: tx.To(),
|
||||
amount: tx.Value(),
|
||||
data: tx.Data(),
|
||||
accessList: tx.AccessList(),
|
||||
isFake: false,
|
||||
}
|
||||
// If baseFee provided, set gasPrice to effectiveGasPrice.
|
||||
if baseFee != nil {
|
||||
msg.gasPrice = math.BigMin(msg.gasPrice.Add(msg.gasTipCap, baseFee), msg.gasFeeCap)
|
||||
}
|
||||
var err error
|
||||
msg.from, err = Sender(s, tx)
|
||||
return msg, err
|
||||
}
|
||||
|
||||
func (m Message) From() common.Address { return m.from }
|
||||
func (m Message) To() *common.Address { return m.to }
|
||||
func (m Message) GasPrice() *big.Int { return m.gasPrice }
|
||||
func (m Message) GasFeeCap() *big.Int { return m.gasFeeCap }
|
||||
func (m Message) GasTipCap() *big.Int { return m.gasTipCap }
|
||||
func (m Message) Value() *big.Int { return m.amount }
|
||||
func (m Message) Gas() uint64 { return m.gasLimit }
|
||||
func (m Message) Nonce() uint64 { return m.nonce }
|
||||
func (m Message) Data() []byte { return m.data }
|
||||
func (m Message) AccessList() AccessList { return m.accessList }
|
||||
func (m Message) IsFake() bool { return m.isFake }
|
||||
func (m Message) IsPre() bool { return m.isPre }
|
||||
|
||||
// copyAddressPtr copies an address.
|
||||
func copyAddressPtr(a *common.Address) *common.Address {
|
||||
if a == nil {
|
||||
|
|
|
|||
|
|
@ -29,7 +29,6 @@ import (
|
|||
"github.com/ethereum/go-ethereum/crypto/bls12381"
|
||||
"github.com/ethereum/go-ethereum/crypto/bn256"
|
||||
"github.com/ethereum/go-ethereum/params"
|
||||
big2 "github.com/holiman/big"
|
||||
"golang.org/x/crypto/ripemd160"
|
||||
)
|
||||
|
||||
|
|
@ -378,9 +377,9 @@ func (c *bigModExp) Run(input []byte) ([]byte, error) {
|
|||
}
|
||||
// Retrieve the operands and execute the exponentiation
|
||||
var (
|
||||
base = new(big2.Int).SetBytes(getData(input, 0, baseLen))
|
||||
exp = new(big2.Int).SetBytes(getData(input, baseLen, expLen))
|
||||
mod = new(big2.Int).SetBytes(getData(input, baseLen+expLen, modLen))
|
||||
base = new(big.Int).SetBytes(getData(input, 0, baseLen))
|
||||
exp = new(big.Int).SetBytes(getData(input, baseLen, expLen))
|
||||
mod = new(big.Int).SetBytes(getData(input, baseLen+expLen, modLen))
|
||||
v []byte
|
||||
)
|
||||
switch {
|
||||
|
|
|
|||
|
|
@ -163,7 +163,7 @@ func gasSStore(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySi
|
|||
return params.NetSstoreDirtyGas, nil
|
||||
}
|
||||
|
||||
// Here come the EIP220 rules:
|
||||
// Here come the EIP2200 rules:
|
||||
//
|
||||
// (0.) If *gasleft* is less than or equal to 2300, fail the current call.
|
||||
// (1.) If current value equals new value (this is a no-op), SLOAD_GAS is deducted.
|
||||
|
|
|
|||
|
|
@ -230,7 +230,7 @@ func (b *EthAPIBackend) GetTd(ctx context.Context, hash common.Hash) *big.Int {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (b *EthAPIBackend) GetEVM(ctx context.Context, msg core.Message, state *state.StateDB, header *types.Header, vmConfig *vm.Config) (*vm.EVM, func() error, error) {
|
||||
func (b *EthAPIBackend) GetEVM(ctx context.Context, msg *core.Message, state *state.StateDB, header *types.Header, vmConfig *vm.Config) (*vm.EVM, func() error, error) {
|
||||
if vmConfig == nil {
|
||||
vmConfig = b.eth.blockchain.GetVMConfig()
|
||||
}
|
||||
|
|
@ -391,6 +391,6 @@ func (b *EthAPIBackend) StateAtBlock(ctx context.Context, block *types.Block, re
|
|||
return b.eth.StateAtBlock(ctx, block, reexec, base, readOnly, preferDisk)
|
||||
}
|
||||
|
||||
func (b *EthAPIBackend) StateAtTransaction(ctx context.Context, block *types.Block, txIndex int, reexec uint64) (core.Message, vm.BlockContext, *state.StateDB, tracers.StateReleaseFunc, error) {
|
||||
func (b *EthAPIBackend) StateAtTransaction(ctx context.Context, block *types.Block, txIndex int, reexec uint64) (*core.Message, vm.BlockContext, *state.StateDB, tracers.StateReleaseFunc, error) {
|
||||
return b.eth.stateAtTransaction(ctx, block, txIndex, reexec)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -189,7 +189,7 @@ func (eth *Ethereum) StateAtBlock(ctx context.Context, block *types.Block, reexe
|
|||
}
|
||||
|
||||
// stateAtTransaction returns the execution environment of a certain transaction.
|
||||
func (eth *Ethereum) stateAtTransaction(ctx context.Context, block *types.Block, txIndex int, reexec uint64) (core.Message, vm.BlockContext, *state.StateDB, tracers.StateReleaseFunc, error) {
|
||||
func (eth *Ethereum) stateAtTransaction(ctx context.Context, block *types.Block, txIndex int, reexec uint64) (*core.Message, vm.BlockContext, *state.StateDB, tracers.StateReleaseFunc, error) {
|
||||
// Short circuit if it's genesis block.
|
||||
if block.NumberU64() == 0 {
|
||||
return nil, vm.BlockContext{}, nil, nil, errors.New("no transaction in genesis")
|
||||
|
|
@ -212,7 +212,7 @@ func (eth *Ethereum) stateAtTransaction(ctx context.Context, block *types.Block,
|
|||
signer := types.MakeSigner(eth.blockchain.Config(), block.Number())
|
||||
for idx, tx := range block.Transactions() {
|
||||
// Assemble the transaction call message and return if the requested offset
|
||||
msg, _ := tx.AsMessage(signer, block.BaseFee())
|
||||
msg, _ := core.TransactionToMessage(tx, signer, block.BaseFee())
|
||||
txContext := core.NewEVMTxContext(msg)
|
||||
context := core.NewEVMBlockContext(block.Header(), eth.blockchain, nil)
|
||||
if idx == txIndex {
|
||||
|
|
|
|||
|
|
@ -87,7 +87,7 @@ type Backend interface {
|
|||
Engine() consensus.Engine
|
||||
ChainDb() ethdb.Database
|
||||
StateAtBlock(ctx context.Context, block *types.Block, reexec uint64, base *state.StateDB, readOnly bool, preferDisk bool) (*state.StateDB, StateReleaseFunc, error)
|
||||
StateAtTransaction(ctx context.Context, block *types.Block, txIndex int, reexec uint64) (core.Message, vm.BlockContext, *state.StateDB, StateReleaseFunc, error)
|
||||
StateAtTransaction(ctx context.Context, block *types.Block, txIndex int, reexec uint64) (*core.Message, vm.BlockContext, *state.StateDB, StateReleaseFunc, error)
|
||||
}
|
||||
|
||||
// API is the collection of tracing APIs exposed over the private debugging endpoint.
|
||||
|
|
@ -293,7 +293,7 @@ func (api *API) traceChain(start, end *types.Block, config *TraceConfig, closed
|
|||
)
|
||||
// Trace all the transactions contained within
|
||||
for i, tx := range task.block.Transactions() {
|
||||
msg, _ := tx.AsMessage(signer, task.block.BaseFee())
|
||||
msg, _ := core.TransactionToMessage(tx, signer, task.block.BaseFee())
|
||||
txctx := &Context{
|
||||
BlockHash: task.block.Hash(),
|
||||
BlockNumber: task.block.Number(),
|
||||
|
|
@ -554,12 +554,12 @@ func (api *API) IntermediateRoots(ctx context.Context, hash common.Hash, config
|
|||
return nil, err
|
||||
}
|
||||
var (
|
||||
msg, _ = tx.AsMessage(signer, block.BaseFee())
|
||||
msg, _ = core.TransactionToMessage(tx, signer, block.BaseFee())
|
||||
txContext = core.NewEVMTxContext(msg)
|
||||
vmenv = vm.NewEVM(vmctx, txContext, statedb, chainConfig, vm.Config{})
|
||||
)
|
||||
statedb.SetTxContext(tx.Hash(), i)
|
||||
if _, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(msg.Gas())); err != nil {
|
||||
if _, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(msg.GasLimit)); err != nil {
|
||||
log.Warn("Tracing intermediate roots did not complete", "txindex", i, "txhash", tx.Hash(), "err", err)
|
||||
// We intentionally don't return the error here: if we do, then the RPC server will not
|
||||
// return the roots. Most likely, the caller already knows that a certain transaction fails to
|
||||
|
|
@ -628,7 +628,7 @@ func (api *API) traceBlock(ctx context.Context, block *types.Block, config *Trac
|
|||
)
|
||||
for i, tx := range txs {
|
||||
// Generate the next state snapshot fast without tracing
|
||||
msg, _ := tx.AsMessage(signer, block.BaseFee())
|
||||
msg, _ := core.TransactionToMessage(tx, signer, block.BaseFee())
|
||||
txctx := &Context{
|
||||
BlockHash: blockHash,
|
||||
BlockNumber: block.Number(),
|
||||
|
|
@ -671,7 +671,7 @@ func (api *API) traceBlockParallel(ctx context.Context, block *types.Block, stat
|
|||
defer pend.Done()
|
||||
// Fetch and execute the next transaction trace tasks
|
||||
for task := range jobs {
|
||||
msg, _ := txs[task.index].AsMessage(signer, block.BaseFee())
|
||||
msg, _ := core.TransactionToMessage(txs[task.index], signer, block.BaseFee())
|
||||
txctx := &Context{
|
||||
BlockHash: blockHash,
|
||||
BlockNumber: block.Number(),
|
||||
|
|
@ -702,10 +702,10 @@ txloop:
|
|||
}
|
||||
|
||||
// Generate the next state snapshot fast without tracing
|
||||
msg, _ := tx.AsMessage(signer, block.BaseFee())
|
||||
msg, _ := core.TransactionToMessage(tx, signer, block.BaseFee())
|
||||
statedb.SetTxContext(tx.Hash(), i)
|
||||
vmenv := vm.NewEVM(blockCtx, core.NewEVMTxContext(msg), statedb, api.backend.ChainConfig(), vm.Config{})
|
||||
if _, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(msg.Gas())); err != nil {
|
||||
if _, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(msg.GasLimit)); err != nil {
|
||||
failed = err
|
||||
break txloop
|
||||
}
|
||||
|
|
@ -782,7 +782,7 @@ func (api *API) standardTraceBlockToFile(ctx context.Context, block *types.Block
|
|||
for i, tx := range block.Transactions() {
|
||||
// Prepare the transaction for un-traced execution
|
||||
var (
|
||||
msg, _ = tx.AsMessage(signer, block.BaseFee())
|
||||
msg, _ = core.TransactionToMessage(tx, signer, block.BaseFee())
|
||||
txContext = core.NewEVMTxContext(msg)
|
||||
vmConf vm.Config
|
||||
dump *os.File
|
||||
|
|
@ -813,7 +813,7 @@ func (api *API) standardTraceBlockToFile(ctx context.Context, block *types.Block
|
|||
// Execute the transaction and flush any traces to disk
|
||||
vmenv := vm.NewEVM(vmctx, txContext, statedb, chainConfig, vmConf)
|
||||
statedb.SetTxContext(tx.Hash(), i)
|
||||
_, err = core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(msg.Gas()))
|
||||
_, err = core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(msg.GasLimit))
|
||||
if writer != nil {
|
||||
writer.Flush()
|
||||
}
|
||||
|
|
@ -947,7 +947,7 @@ func (api *API) TraceCall(ctx context.Context, args ethapi.TransactionArgs, bloc
|
|||
// traceTx configures a new tracer according to the provided configuration, and
|
||||
// executes the given message in the provided environment. The return value will
|
||||
// be tracer dependent.
|
||||
func (api *API) traceTx(ctx context.Context, message core.Message, txctx *Context, vmctx vm.BlockContext, statedb *state.StateDB, config *TraceConfig) (interface{}, error) {
|
||||
func (api *API) traceTx(ctx context.Context, message *core.Message, txctx *Context, vmctx vm.BlockContext, statedb *state.StateDB, config *TraceConfig) (interface{}, error) {
|
||||
var (
|
||||
tracer Tracer
|
||||
err error
|
||||
|
|
@ -986,7 +986,7 @@ func (api *API) traceTx(ctx context.Context, message core.Message, txctx *Contex
|
|||
|
||||
// Call Prepare to clear out the statedb access list
|
||||
statedb.SetTxContext(txctx.TxHash, txctx.TxIndex)
|
||||
if _, err = core.ApplyMessage(vmenv, message, new(core.GasPool).AddGas(message.Gas())); err != nil {
|
||||
if _, err = core.ApplyMessage(vmenv, message, new(core.GasPool).AddGas(message.GasLimit)); err != nil {
|
||||
return nil, fmt.Errorf("tracing failed: %w", err)
|
||||
}
|
||||
return tracer.GetResult()
|
||||
|
|
|
|||
|
|
@ -156,7 +156,7 @@ func (b *testBackend) StateAtBlock(ctx context.Context, block *types.Block, reex
|
|||
return statedb, release, nil
|
||||
}
|
||||
|
||||
func (b *testBackend) StateAtTransaction(ctx context.Context, block *types.Block, txIndex int, reexec uint64) (core.Message, vm.BlockContext, *state.StateDB, StateReleaseFunc, error) {
|
||||
func (b *testBackend) StateAtTransaction(ctx context.Context, block *types.Block, txIndex int, reexec uint64) (*core.Message, vm.BlockContext, *state.StateDB, StateReleaseFunc, error) {
|
||||
parent := b.chain.GetBlock(block.ParentHash(), block.NumberU64()-1)
|
||||
if parent == nil {
|
||||
return nil, vm.BlockContext{}, nil, nil, errBlockNotFound
|
||||
|
|
@ -171,7 +171,7 @@ func (b *testBackend) StateAtTransaction(ctx context.Context, block *types.Block
|
|||
// Recompute transactions up to the target index.
|
||||
signer := types.MakeSigner(b.chainConfig, block.Number())
|
||||
for idx, tx := range block.Transactions() {
|
||||
msg, _ := tx.AsMessage(signer, block.BaseFee())
|
||||
msg, _ := core.TransactionToMessage(tx, signer, block.BaseFee())
|
||||
txContext := core.NewEVMTxContext(msg)
|
||||
context := core.NewEVMBlockContext(block.Header(), b.chain, nil)
|
||||
if idx == txIndex {
|
||||
|
|
|
|||
|
|
@ -145,7 +145,7 @@ func testCallTracer(tracerName string, dirPath string, t *testing.T) {
|
|||
t.Fatalf("failed to create call tracer: %v", err)
|
||||
}
|
||||
evm := vm.NewEVM(context, txContext, statedb, test.Genesis.Config, vm.Config{Debug: true, Tracer: tracer})
|
||||
msg, err := tx.AsMessage(signer, nil)
|
||||
msg, err := core.TransactionToMessage(tx, signer, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to prepare transaction for tracing: %v", err)
|
||||
}
|
||||
|
|
@ -220,7 +220,7 @@ func benchTracer(tracerName string, test *callTracerTest, b *testing.B) {
|
|||
b.Fatalf("failed to parse testcase input: %v", err)
|
||||
}
|
||||
signer := types.MakeSigner(test.Genesis.Config, new(big.Int).SetUint64(uint64(test.Context.Number)))
|
||||
msg, err := tx.AsMessage(signer, nil)
|
||||
msg, err := core.TransactionToMessage(tx, signer, nil)
|
||||
if err != nil {
|
||||
b.Fatalf("failed to prepare transaction for tracing: %v", err)
|
||||
}
|
||||
|
|
@ -314,7 +314,7 @@ func TestZeroValueToNotExitCall(t *testing.T) {
|
|||
t.Fatalf("failed to create call tracer: %v", err)
|
||||
}
|
||||
evm := vm.NewEVM(context, txContext, statedb, params.MainnetChainConfig, vm.Config{Debug: true, Tracer: tracer})
|
||||
msg, err := tx.AsMessage(signer, nil)
|
||||
msg, err := core.TransactionToMessage(tx, signer, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to prepare transaction for tracing: %v", err)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@ func flatCallTracerTestRunner(tracerName string, filename string, dirPath string
|
|||
}
|
||||
evm := vm.NewEVM(context, txContext, statedb, test.Genesis.Config, vm.Config{Debug: true, Tracer: tracer})
|
||||
|
||||
msg, err := tx.AsMessage(signer, nil)
|
||||
msg, err := core.TransactionToMessage(tx, signer, nil)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to prepare transaction for tracing: %v", err)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -115,7 +115,7 @@ func testPrestateDiffTracer(tracerName string, dirPath string, t *testing.T) {
|
|||
t.Fatalf("failed to create call tracer: %v", err)
|
||||
}
|
||||
evm := vm.NewEVM(context, txContext, statedb, test.Genesis.Config, vm.Config{Debug: true, Tracer: tracer})
|
||||
msg, err := tx.AsMessage(signer, nil)
|
||||
msg, err := core.TransactionToMessage(tx, signer, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to prepare transaction for tracing: %v", err)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -88,7 +88,7 @@ func BenchmarkTransactionTrace(b *testing.B) {
|
|||
//EnableReturnData: false,
|
||||
})
|
||||
evm := vm.NewEVM(context, txContext, statedb, params.AllEthashProtocolChanges, vm.Config{Debug: true, Tracer: tracer})
|
||||
msg, err := tx.AsMessage(signer, nil)
|
||||
msg, err := core.TransactionToMessage(tx, signer, nil)
|
||||
if err != nil {
|
||||
b.Fatalf("failed to prepare transaction for tracing: %v", err)
|
||||
}
|
||||
|
|
|
|||
1
go.mod
1
go.mod
|
|
@ -37,7 +37,6 @@ require (
|
|||
github.com/gorilla/websocket v1.4.2
|
||||
github.com/graph-gophers/graphql-go v1.3.0
|
||||
github.com/hashicorp/go-bexpr v0.1.10
|
||||
github.com/holiman/big v0.0.0-20221017200358-a027dc42d04e
|
||||
github.com/holiman/bloomfilter/v2 v2.0.3
|
||||
github.com/holiman/uint256 v1.2.0
|
||||
github.com/huin/goupnp v1.0.3
|
||||
|
|
|
|||
2
go.sum
2
go.sum
|
|
@ -300,8 +300,6 @@ github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09
|
|||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
||||
github.com/holiman/big v0.0.0-20221017200358-a027dc42d04e h1:pIYdhNkDh+YENVNi3gto8n9hAmRxKxoar0iE6BLucjw=
|
||||
github.com/holiman/big v0.0.0-20221017200358-a027dc42d04e/go.mod h1:j9cQbcqHQujT0oKJ38PylVfqohClLr3CvDC+Qcg+lhU=
|
||||
github.com/holiman/bloomfilter/v2 v2.0.3 h1:73e0e/V0tCydx14a0SCYS/EWCxgwLZ18CZcZKVu0fao=
|
||||
github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iURXE7ZOP9L9hSkA=
|
||||
github.com/holiman/uint256 v1.2.0 h1:gpSYcPLWGv4sG43I2mVLiDZCNDh/EpGjSk8tmtxitHM=
|
||||
|
|
|
|||
|
|
@ -1011,7 +1011,7 @@ func DoCall(ctx context.Context, b Backend, args TransactionArgs, blockNrOrHash
|
|||
return nil, fmt.Errorf("execution aborted (timeout = %v)", timeout)
|
||||
}
|
||||
if err != nil {
|
||||
return result, fmt.Errorf("err: %w (supplied gas %d)", err, msg.Gas())
|
||||
return result, fmt.Errorf("err: %w (supplied gas %d)", err, msg.GasLimit)
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
|
@ -1484,7 +1484,7 @@ func AccessList(ctx context.Context, b Backend, blockNrOrHash rpc.BlockNumberOrH
|
|||
if err != nil {
|
||||
return nil, 0, nil, err
|
||||
}
|
||||
res, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(msg.Gas()))
|
||||
res, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(msg.GasLimit))
|
||||
if err != nil {
|
||||
return nil, 0, nil, fmt.Errorf("failed to apply transaction: %v err: %v", args.toTransaction().Hash(), err)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ type Backend interface {
|
|||
PendingBlockAndReceipts() (*types.Block, types.Receipts)
|
||||
GetReceipts(ctx context.Context, hash common.Hash) (types.Receipts, error)
|
||||
GetTd(ctx context.Context, hash common.Hash) *big.Int
|
||||
GetEVM(ctx context.Context, msg core.Message, state *state.StateDB, header *types.Header, vmConfig *vm.Config) (*vm.EVM, func() error, error)
|
||||
GetEVM(ctx context.Context, msg *core.Message, state *state.StateDB, header *types.Header, vmConfig *vm.Config) (*vm.EVM, func() error, error)
|
||||
SubscribeChainEvent(ch chan<- core.ChainEvent) event.Subscription
|
||||
SubscribeChainHeadEvent(ch chan<- core.ChainHeadEvent) event.Subscription
|
||||
SubscribeChainSideEvent(ch chan<- core.ChainSideEvent) event.Subscription
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ import (
|
|||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
"github.com/ethereum/go-ethereum/common/math"
|
||||
"github.com/ethereum/go-ethereum/core"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
"github.com/ethereum/go-ethereum/rpc"
|
||||
|
|
@ -199,10 +200,10 @@ func (args *TransactionArgs) setLondonFeeDefaults(ctx context.Context, head *typ
|
|||
// ToMessage converts the transaction arguments to the Message type used by the
|
||||
// core evm. This method is used in calls and traces that do not require a real
|
||||
// live transaction.
|
||||
func (args *TransactionArgs) ToMessage(globalGasCap uint64, baseFee *big.Int) (types.Message, error) {
|
||||
func (args *TransactionArgs) ToMessage(globalGasCap uint64, baseFee *big.Int) (*core.Message, error) {
|
||||
// Reject invalid combinations of pre- and post-1559 fee styles
|
||||
if args.GasPrice != nil && (args.MaxFeePerGas != nil || args.MaxPriorityFeePerGas != nil) {
|
||||
return types.Message{}, errors.New("both gasPrice and (maxFeePerGas or maxPriorityFeePerGas) specified")
|
||||
return nil, errors.New("both gasPrice and (maxFeePerGas or maxPriorityFeePerGas) specified")
|
||||
}
|
||||
// Set sender address or use zero address if none specified.
|
||||
addr := args.from()
|
||||
|
|
@ -263,7 +264,18 @@ func (args *TransactionArgs) ToMessage(globalGasCap uint64, baseFee *big.Int) (t
|
|||
if args.AccessList != nil {
|
||||
accessList = *args.AccessList
|
||||
}
|
||||
msg := types.NewMessage(addr, args.To, 0, value, gas, gasPrice, gasFeeCap, gasTipCap, data, accessList, true, false)
|
||||
msg := &core.Message{
|
||||
From: addr,
|
||||
To: args.To,
|
||||
Value: value,
|
||||
GasLimit: gas,
|
||||
GasPrice: gasPrice,
|
||||
GasFeeCap: gasFeeCap,
|
||||
GasTipCap: gasTipCap,
|
||||
Data: data,
|
||||
AccessList: accessList,
|
||||
SkipAccountChecks: true,
|
||||
}
|
||||
return msg, nil
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -305,7 +305,7 @@ func (b *backendMock) GetLogs(ctx context.Context, blockHash common.Hash, number
|
|||
return nil, nil
|
||||
}
|
||||
func (b *backendMock) GetTd(ctx context.Context, hash common.Hash) *big.Int { return nil }
|
||||
func (b *backendMock) GetEVM(ctx context.Context, msg core.Message, state *state.StateDB, header *types.Header, vmConfig *vm.Config) (*vm.EVM, func() error, error) {
|
||||
func (b *backendMock) GetEVM(ctx context.Context, msg *core.Message, state *state.StateDB, header *types.Header, vmConfig *vm.Config) (*vm.EVM, func() error, error) {
|
||||
return nil, nil, nil
|
||||
}
|
||||
func (b *backendMock) SubscribeChainEvent(ch chan<- core.ChainEvent) event.Subscription { return nil }
|
||||
|
|
|
|||
|
|
@ -190,7 +190,7 @@ func (b *LesApiBackend) GetTd(ctx context.Context, hash common.Hash) *big.Int {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (b *LesApiBackend) GetEVM(ctx context.Context, msg core.Message, state *state.StateDB, header *types.Header, vmConfig *vm.Config) (*vm.EVM, func() error, error) {
|
||||
func (b *LesApiBackend) GetEVM(ctx context.Context, msg *core.Message, state *state.StateDB, header *types.Header, vmConfig *vm.Config) (*vm.EVM, func() error, error) {
|
||||
if vmConfig == nil {
|
||||
vmConfig = new(vm.Config)
|
||||
}
|
||||
|
|
@ -336,6 +336,6 @@ func (b *LesApiBackend) StateAtBlock(ctx context.Context, block *types.Block, re
|
|||
return b.eth.stateAtBlock(ctx, block, reexec)
|
||||
}
|
||||
|
||||
func (b *LesApiBackend) StateAtTransaction(ctx context.Context, block *types.Block, txIndex int, reexec uint64) (core.Message, vm.BlockContext, *state.StateDB, tracers.StateReleaseFunc, error) {
|
||||
func (b *LesApiBackend) StateAtTransaction(ctx context.Context, block *types.Block, txIndex int, reexec uint64) (*core.Message, vm.BlockContext, *state.StateDB, tracers.StateReleaseFunc, error) {
|
||||
return b.eth.stateAtTransaction(ctx, block, txIndex, reexec)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -116,12 +116,6 @@ func TestOdrContractCallLes2(t *testing.T) { testOdr(t, 2, 2, true, odrContractC
|
|||
func TestOdrContractCallLes3(t *testing.T) { testOdr(t, 3, 2, true, odrContractCall) }
|
||||
func TestOdrContractCallLes4(t *testing.T) { testOdr(t, 4, 2, true, odrContractCall) }
|
||||
|
||||
type callmsg struct {
|
||||
types.Message
|
||||
}
|
||||
|
||||
func (callmsg) CheckNonce() bool { return false }
|
||||
|
||||
func odrContractCall(ctx context.Context, db ethdb.Database, config *params.ChainConfig, bc *core.BlockChain, lc *light.LightChain, bhash common.Hash) []byte {
|
||||
data := common.Hex2Bytes("60CD26850000000000000000000000000000000000000000000000000000000000000000")
|
||||
|
||||
|
|
@ -136,7 +130,17 @@ func odrContractCall(ctx context.Context, db ethdb.Database, config *params.Chai
|
|||
from := statedb.GetOrNewStateObject(bankAddr)
|
||||
from.SetBalance(math.MaxBig256)
|
||||
|
||||
msg := callmsg{types.NewMessage(from.Address(), &testContractAddr, 0, new(big.Int), 100000, big.NewInt(params.InitialBaseFee), big.NewInt(params.InitialBaseFee), new(big.Int), data, nil, true, false)}
|
||||
msg := &core.Message{
|
||||
From: from.Address(),
|
||||
To: &testContractAddr,
|
||||
Value: new(big.Int),
|
||||
GasLimit: 100000,
|
||||
GasPrice: big.NewInt(params.InitialBaseFee),
|
||||
GasFeeCap: big.NewInt(params.InitialBaseFee),
|
||||
GasTipCap: new(big.Int),
|
||||
Data: data,
|
||||
SkipAccountChecks: true,
|
||||
}
|
||||
|
||||
context := core.NewEVMBlockContext(header, bc, nil)
|
||||
txContext := core.NewEVMTxContext(msg)
|
||||
|
|
@ -151,7 +155,17 @@ func odrContractCall(ctx context.Context, db ethdb.Database, config *params.Chai
|
|||
header := lc.GetHeaderByHash(bhash)
|
||||
state := light.NewState(ctx, header, lc.Odr())
|
||||
state.SetBalance(bankAddr, math.MaxBig256)
|
||||
msg := callmsg{types.NewMessage(bankAddr, &testContractAddr, 0, new(big.Int), 100000, big.NewInt(params.InitialBaseFee), big.NewInt(params.InitialBaseFee), new(big.Int), data, nil, true, false)}
|
||||
msg := &core.Message{
|
||||
From: bankAddr,
|
||||
To: &testContractAddr,
|
||||
Value: new(big.Int),
|
||||
GasLimit: 100000,
|
||||
GasPrice: big.NewInt(params.InitialBaseFee),
|
||||
GasFeeCap: big.NewInt(params.InitialBaseFee),
|
||||
GasTipCap: new(big.Int),
|
||||
Data: data,
|
||||
SkipAccountChecks: true,
|
||||
}
|
||||
context := core.NewEVMBlockContext(header, lc, nil)
|
||||
txContext := core.NewEVMTxContext(msg)
|
||||
vmenv := vm.NewEVM(context, txContext, state, config, vm.Config{NoBaseFee: true})
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ func (leth *LightEthereum) stateAtBlock(ctx context.Context, block *types.Block,
|
|||
}
|
||||
|
||||
// stateAtTransaction returns the execution environment of a certain transaction.
|
||||
func (leth *LightEthereum) stateAtTransaction(ctx context.Context, block *types.Block, txIndex int, reexec uint64) (core.Message, vm.BlockContext, *state.StateDB, tracers.StateReleaseFunc, error) {
|
||||
func (leth *LightEthereum) stateAtTransaction(ctx context.Context, block *types.Block, txIndex int, reexec uint64) (*core.Message, vm.BlockContext, *state.StateDB, tracers.StateReleaseFunc, error) {
|
||||
// Short circuit if it's genesis block.
|
||||
if block.NumberU64() == 0 {
|
||||
return nil, vm.BlockContext{}, nil, nil, errors.New("no transaction in genesis")
|
||||
|
|
@ -60,7 +60,7 @@ func (leth *LightEthereum) stateAtTransaction(ctx context.Context, block *types.
|
|||
signer := types.MakeSigner(leth.blockchain.Config(), block.Number())
|
||||
for idx, tx := range block.Transactions() {
|
||||
// Assemble the transaction call message and return if the requested offset
|
||||
msg, _ := tx.AsMessage(signer, block.BaseFee())
|
||||
msg, _ := core.TransactionToMessage(tx, signer, block.BaseFee())
|
||||
txContext := core.NewEVMTxContext(msg)
|
||||
context := core.NewEVMBlockContext(block.Header(), leth.blockchain, nil)
|
||||
statedb.SetTxContext(tx.Hash(), idx)
|
||||
|
|
|
|||
|
|
@ -174,12 +174,6 @@ func odrAccounts(ctx context.Context, db ethdb.Database, bc *core.BlockChain, lc
|
|||
|
||||
func TestOdrContractCallLes2(t *testing.T) { testChainOdr(t, 1, odrContractCall) }
|
||||
|
||||
type callmsg struct {
|
||||
types.Message
|
||||
}
|
||||
|
||||
func (callmsg) CheckNonce() bool { return false }
|
||||
|
||||
func odrContractCall(ctx context.Context, db ethdb.Database, bc *core.BlockChain, lc *LightChain, bhash common.Hash) ([]byte, error) {
|
||||
data := common.Hex2Bytes("60CD26850000000000000000000000000000000000000000000000000000000000000000")
|
||||
config := params.TestChainConfig
|
||||
|
|
@ -205,7 +199,17 @@ func odrContractCall(ctx context.Context, db ethdb.Database, bc *core.BlockChain
|
|||
|
||||
// Perform read-only call.
|
||||
st.SetBalance(testBankAddress, math.MaxBig256)
|
||||
msg := callmsg{types.NewMessage(testBankAddress, &testContractAddr, 0, new(big.Int), 1000000, big.NewInt(params.InitialBaseFee), big.NewInt(params.InitialBaseFee), new(big.Int), data, nil, true, false)}
|
||||
msg := &core.Message{
|
||||
From: testBankAddress,
|
||||
To: &testContractAddr,
|
||||
Value: new(big.Int),
|
||||
GasLimit: 1000000,
|
||||
GasPrice: big.NewInt(params.InitialBaseFee),
|
||||
GasFeeCap: big.NewInt(params.InitialBaseFee),
|
||||
GasTipCap: new(big.Int),
|
||||
Data: data,
|
||||
SkipAccountChecks: true,
|
||||
}
|
||||
txContext := core.NewEVMTxContext(msg)
|
||||
context := core.NewEVMBlockContext(header, chain, nil)
|
||||
vmenv := vm.NewEVM(context, txContext, st, config, vm.Config{NoBaseFee: true})
|
||||
|
|
|
|||
|
|
@ -125,7 +125,5 @@ compile_fuzzer tests/fuzzers/snap FuzzSRange fuzz_storage_range
|
|||
compile_fuzzer tests/fuzzers/snap FuzzByteCodes fuzz_byte_codes
|
||||
compile_fuzzer tests/fuzzers/snap FuzzTrieNodes fuzz_trie_nodes
|
||||
|
||||
compile_fuzzer tests/fuzzers/modexp Fuzz fuzzModexp
|
||||
|
||||
#TODO: move this to tests/fuzzers, if possible
|
||||
compile_fuzzer crypto/blake2b Fuzz fuzzBlake2b
|
||||
|
|
|
|||
|
|
@ -1057,7 +1057,7 @@ func (srv *Server) runPeer(p *Peer) {
|
|||
// Broadcast peer drop to external subscribers. This needs to be
|
||||
// after the send to delpeer so subscribers have a consistent view of
|
||||
// the peer set (i.e. Server.Peers() doesn't include the peer when the
|
||||
// event is received.
|
||||
// event is received).
|
||||
srv.peerFeed.Send(&PeerEvent{
|
||||
Type: PeerEventTypeDrop,
|
||||
Peer: p.ID(),
|
||||
|
|
|
|||
|
|
@ -22,14 +22,10 @@ import "github.com/ethereum/go-ethereum/common"
|
|||
// the main Ethereum network.
|
||||
var MainnetBootnodes = []string{
|
||||
// Ethereum Foundation Go Bootnodes
|
||||
"enode://d860a01f9722d78051619d1e2351aba3f43f943f6f00718d1b9baa4101932a1f5011f16bb2b1bb35db20d6fe28fa0bf09636d26a87d31de9ec6203eeedb1f666@18.138.108.67:30303", // bootnode-aws-ap-southeast-1-001
|
||||
"enode://22a8232c3abc76a16ae9d6c3b164f98775fe226f0917b0ca871128a74a8e9630b458460865bab457221f1d448dd9791d24c4e5d88786180ac185df813a68d4de@3.209.45.79:30303", // bootnode-aws-us-east-1-001
|
||||
"enode://8499da03c47d637b20eee24eec3c356c9a2e6148d6fe25ca195c7949ab8ec2c03e3556126b0d7ed644675e78c4318b08691b7b57de10e5f0d40d05b09238fa0a@52.187.207.27:30303", // bootnode-azure-australiaeast-001
|
||||
"enode://103858bdb88756c71f15e9b5e09b56dc1be52f0a5021d46301dbbfb7e130029cc9d0d6f73f693bc29b665770fff7da4d34f3c6379fe12721b5d7a0bcb5ca1fc1@191.234.162.198:30303", // bootnode-azure-brazilsouth-001
|
||||
"enode://715171f50508aba88aecd1250af392a45a330af91d7b90701c436b618c86aaa1589c9184561907bebbb56439b8f8787bc01f49a7c77276c58c1b09822d75e8e8@52.231.165.108:30303", // bootnode-azure-koreasouth-001
|
||||
"enode://5d6d7cd20d6da4bb83a1d28cadb5d409b64edf314c0335df658c1a54e32c7c4a7ab7823d57c39b6a757556e68ff1df17c748b698544a55cb488b52479a92b60f@104.42.217.25:30303", // bootnode-azure-westus-001
|
||||
"enode://2b252ab6a1d0f971d9722cb839a42cb81db019ba44c08754628ab4a823487071b5695317c8ccd085219c3a03af063495b2f1da8d18218da2d6a82981b45e6ffc@65.108.70.101:30303", // bootnode-hetzner-hel
|
||||
"enode://4aeb4ab6c14b23e2c4cfdce879c04b0748a20d8e9b59e25ded2a08143e265c6c25936e74cbc8e641e3312ca288673d91f2f93f8e277de3cfa444ecdaaf982052@157.90.35.166:30303", // bootnode-hetzner-fsn
|
||||
"enode://d860a01f9722d78051619d1e2351aba3f43f943f6f00718d1b9baa4101932a1f5011f16bb2b1bb35db20d6fe28fa0bf09636d26a87d31de9ec6203eeedb1f666@18.138.108.67:30303", // bootnode-aws-ap-southeast-1-001
|
||||
"enode://22a8232c3abc76a16ae9d6c3b164f98775fe226f0917b0ca871128a74a8e9630b458460865bab457221f1d448dd9791d24c4e5d88786180ac185df813a68d4de@3.209.45.79:30303", // bootnode-aws-us-east-1-001
|
||||
"enode://2b252ab6a1d0f971d9722cb839a42cb81db019ba44c08754628ab4a823487071b5695317c8ccd085219c3a03af063495b2f1da8d18218da2d6a82981b45e6ffc@65.108.70.101:30303", // bootnode-hetzner-hel
|
||||
"enode://4aeb4ab6c14b23e2c4cfdce879c04b0748a20d8e9b59e25ded2a08143e265c6c25936e74cbc8e641e3312ca288673d91f2f93f8e277de3cfa444ecdaaf982052@157.90.35.166:30303", // bootnode-hetzner-fsn
|
||||
}
|
||||
|
||||
// SepoliaBootnodes are the enode URLs of the P2P bootstrap nodes running on the
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ var (
|
|||
const (
|
||||
VersionMajor = 1 // Major version component of the current release
|
||||
VersionMinor = 11 // Minor version component of the current release
|
||||
VersionPatch = 3 // Patch version component of the current release
|
||||
VersionPatch = 4 // Patch version component of the current release
|
||||
VersionMeta = "stable" // Version metadata to append to the version string
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -742,112 +742,30 @@ func isPrimitiveTypeValid(primitiveType string) bool {
|
|||
primitiveType == "bool" ||
|
||||
primitiveType == "bool[]" ||
|
||||
primitiveType == "string" ||
|
||||
primitiveType == "string[]" {
|
||||
return true
|
||||
}
|
||||
if primitiveType == "bytes" ||
|
||||
primitiveType == "string[]" ||
|
||||
primitiveType == "bytes" ||
|
||||
primitiveType == "bytes[]" ||
|
||||
primitiveType == "bytes1" ||
|
||||
primitiveType == "bytes1[]" ||
|
||||
primitiveType == "bytes2" ||
|
||||
primitiveType == "bytes2[]" ||
|
||||
primitiveType == "bytes3" ||
|
||||
primitiveType == "bytes3[]" ||
|
||||
primitiveType == "bytes4" ||
|
||||
primitiveType == "bytes4[]" ||
|
||||
primitiveType == "bytes5" ||
|
||||
primitiveType == "bytes5[]" ||
|
||||
primitiveType == "bytes6" ||
|
||||
primitiveType == "bytes6[]" ||
|
||||
primitiveType == "bytes7" ||
|
||||
primitiveType == "bytes7[]" ||
|
||||
primitiveType == "bytes8" ||
|
||||
primitiveType == "bytes8[]" ||
|
||||
primitiveType == "bytes9" ||
|
||||
primitiveType == "bytes9[]" ||
|
||||
primitiveType == "bytes10" ||
|
||||
primitiveType == "bytes10[]" ||
|
||||
primitiveType == "bytes11" ||
|
||||
primitiveType == "bytes11[]" ||
|
||||
primitiveType == "bytes12" ||
|
||||
primitiveType == "bytes12[]" ||
|
||||
primitiveType == "bytes13" ||
|
||||
primitiveType == "bytes13[]" ||
|
||||
primitiveType == "bytes14" ||
|
||||
primitiveType == "bytes14[]" ||
|
||||
primitiveType == "bytes15" ||
|
||||
primitiveType == "bytes15[]" ||
|
||||
primitiveType == "bytes16" ||
|
||||
primitiveType == "bytes16[]" ||
|
||||
primitiveType == "bytes17" ||
|
||||
primitiveType == "bytes17[]" ||
|
||||
primitiveType == "bytes18" ||
|
||||
primitiveType == "bytes18[]" ||
|
||||
primitiveType == "bytes19" ||
|
||||
primitiveType == "bytes19[]" ||
|
||||
primitiveType == "bytes20" ||
|
||||
primitiveType == "bytes20[]" ||
|
||||
primitiveType == "bytes21" ||
|
||||
primitiveType == "bytes21[]" ||
|
||||
primitiveType == "bytes22" ||
|
||||
primitiveType == "bytes22[]" ||
|
||||
primitiveType == "bytes23" ||
|
||||
primitiveType == "bytes23[]" ||
|
||||
primitiveType == "bytes24" ||
|
||||
primitiveType == "bytes24[]" ||
|
||||
primitiveType == "bytes25" ||
|
||||
primitiveType == "bytes25[]" ||
|
||||
primitiveType == "bytes26" ||
|
||||
primitiveType == "bytes26[]" ||
|
||||
primitiveType == "bytes27" ||
|
||||
primitiveType == "bytes27[]" ||
|
||||
primitiveType == "bytes28" ||
|
||||
primitiveType == "bytes28[]" ||
|
||||
primitiveType == "bytes29" ||
|
||||
primitiveType == "bytes29[]" ||
|
||||
primitiveType == "bytes30" ||
|
||||
primitiveType == "bytes30[]" ||
|
||||
primitiveType == "bytes31" ||
|
||||
primitiveType == "bytes31[]" ||
|
||||
primitiveType == "bytes32" ||
|
||||
primitiveType == "bytes32[]" {
|
||||
return true
|
||||
}
|
||||
if primitiveType == "int" ||
|
||||
primitiveType == "int" ||
|
||||
primitiveType == "int[]" ||
|
||||
primitiveType == "int8" ||
|
||||
primitiveType == "int8[]" ||
|
||||
primitiveType == "int16" ||
|
||||
primitiveType == "int16[]" ||
|
||||
primitiveType == "int32" ||
|
||||
primitiveType == "int32[]" ||
|
||||
primitiveType == "int64" ||
|
||||
primitiveType == "int64[]" ||
|
||||
primitiveType == "int96" ||
|
||||
primitiveType == "int96[]" ||
|
||||
primitiveType == "int128" ||
|
||||
primitiveType == "int128[]" ||
|
||||
primitiveType == "int256" ||
|
||||
primitiveType == "int256[]" {
|
||||
primitiveType == "uint" ||
|
||||
primitiveType == "uint[]" {
|
||||
return true
|
||||
}
|
||||
if primitiveType == "uint" ||
|
||||
primitiveType == "uint[]" ||
|
||||
primitiveType == "uint8" ||
|
||||
primitiveType == "uint8[]" ||
|
||||
primitiveType == "uint16" ||
|
||||
primitiveType == "uint16[]" ||
|
||||
primitiveType == "uint32" ||
|
||||
primitiveType == "uint32[]" ||
|
||||
primitiveType == "uint64" ||
|
||||
primitiveType == "uint64[]" ||
|
||||
primitiveType == "uint96" ||
|
||||
primitiveType == "uint96[]" ||
|
||||
primitiveType == "uint128" ||
|
||||
primitiveType == "uint128[]" ||
|
||||
primitiveType == "uint256" ||
|
||||
primitiveType == "uint256[]" {
|
||||
return true
|
||||
// For 'bytesN', 'bytesN[]', we allow N from 1 to 32
|
||||
for n := 1; n <= 32; n++ {
|
||||
// e.g. 'bytes28' or 'bytes28[]'
|
||||
if primitiveType == fmt.Sprintf("bytes%d", n) || primitiveType == fmt.Sprintf("bytes%d[]", n) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
// For 'intN','intN[]' and 'uintN','uintN[]' we allow N in increments of 8, from 8 up to 256
|
||||
for n := 8; n <= 256; n += 8 {
|
||||
if primitiveType == fmt.Sprintf("int%d", n) || primitiveType == fmt.Sprintf("int%d[]", n) {
|
||||
return true
|
||||
}
|
||||
if primitiveType == fmt.Sprintf("uint%d", n) || primitiveType == fmt.Sprintf("uint%d[]", n) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2020 The go-ethereum Authors
|
||||
// Copyright 2023 The go-ethereum Authors
|
||||
// This file is part of the go-ethereum library.
|
||||
//
|
||||
// The go-ethereum library is free software: you can redistribute it and/or modify
|
||||
|
|
@ -14,27 +14,27 @@
|
|||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package main
|
||||
package apitypes
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
import "testing"
|
||||
|
||||
"github.com/ethereum/go-ethereum/tests/fuzzers/modexp"
|
||||
)
|
||||
|
||||
func main() {
|
||||
if len(os.Args) != 2 {
|
||||
fmt.Fprintf(os.Stderr, "Usage: debug <file>\n")
|
||||
fmt.Fprintf(os.Stderr, "Example\n")
|
||||
fmt.Fprintf(os.Stderr, " $ debug ../crashers/4bbef6857c733a87ecf6fd8b9e7238f65eb9862a\n")
|
||||
os.Exit(1)
|
||||
func TestIsPrimitive(t *testing.T) {
|
||||
// Expected positives
|
||||
for i, tc := range []string{
|
||||
"int24", "int24[]", "uint88", "uint88[]", "uint", "uint[]", "int256", "int256[]",
|
||||
"uint96", "uint96[]", "int96", "int96[]", "bytes17[]", "bytes17",
|
||||
} {
|
||||
if !isPrimitiveTypeValid(tc) {
|
||||
t.Errorf("test %d: expected '%v' to be a valid primitive", i, tc)
|
||||
}
|
||||
}
|
||||
crasher := os.Args[1]
|
||||
data, err := os.ReadFile(crasher)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "error loading crasher %v: %v", crasher, err)
|
||||
os.Exit(1)
|
||||
// Expected negatives
|
||||
for i, tc := range []string{
|
||||
"int257", "int257[]", "uint88 ", "uint88 []", "uint257", "uint-1[]",
|
||||
"uint0", "uint0[]", "int95", "int95[]", "uint1", "uint1[]", "bytes33[]", "bytess",
|
||||
} {
|
||||
if isPrimitiveTypeValid(tc) {
|
||||
t.Errorf("test %d: expected '%v' to not be a valid primitive", i, tc)
|
||||
}
|
||||
}
|
||||
modexp.Fuzz(data)
|
||||
}
|
||||
|
|
@ -1,90 +0,0 @@
|
|||
// Copyright 2022 The go-ethereum Authors
|
||||
// This file is part of the go-ethereum library.
|
||||
//
|
||||
// The go-ethereum library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// The go-ethereum library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package modexp
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/big"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/core/vm"
|
||||
big2 "github.com/holiman/big"
|
||||
)
|
||||
|
||||
// Fuzz is the fuzzing entry-point.
|
||||
// The function must return
|
||||
//
|
||||
// - 1 if the fuzzer should increase priority of the
|
||||
// given input during subsequent fuzzing (for example, the input is lexically
|
||||
// correct and was parsed successfully);
|
||||
// - -1 if the input must not be added to corpus even if gives new coverage; and
|
||||
// - 0 otherwise
|
||||
//
|
||||
// other values are reserved for future use.
|
||||
func Fuzz(input []byte) int {
|
||||
if len(input) <= 96 {
|
||||
return -1
|
||||
}
|
||||
// Abort on too expensive inputs
|
||||
precomp := vm.PrecompiledContractsBerlin[common.BytesToAddress([]byte{5})]
|
||||
if gas := precomp.RequiredGas(input); gas > 40_000_000 {
|
||||
return 0
|
||||
}
|
||||
var (
|
||||
baseLen = new(big.Int).SetBytes(getData(input, 0, 32)).Uint64()
|
||||
expLen = new(big.Int).SetBytes(getData(input, 32, 32)).Uint64()
|
||||
modLen = new(big.Int).SetBytes(getData(input, 64, 32)).Uint64()
|
||||
)
|
||||
// Handle a special case when both the base and mod length is zero
|
||||
if baseLen == 0 && modLen == 0 {
|
||||
return -1
|
||||
}
|
||||
input = input[96:]
|
||||
// Retrieve the operands and execute the exponentiation
|
||||
var (
|
||||
base = new(big.Int).SetBytes(getData(input, 0, baseLen))
|
||||
exp = new(big.Int).SetBytes(getData(input, baseLen, expLen))
|
||||
mod = new(big.Int).SetBytes(getData(input, baseLen+expLen, modLen))
|
||||
base2 = new(big2.Int).SetBytes(getData(input, 0, baseLen))
|
||||
exp2 = new(big2.Int).SetBytes(getData(input, baseLen, expLen))
|
||||
mod2 = new(big2.Int).SetBytes(getData(input, baseLen+expLen, modLen))
|
||||
)
|
||||
if mod.BitLen() == 0 {
|
||||
// Modulo 0 is undefined, return zero
|
||||
return -1
|
||||
}
|
||||
var a = new(big2.Int).Exp(base2, exp2, mod2).String()
|
||||
var b = new(big.Int).Exp(base, exp, mod).String()
|
||||
if a != b {
|
||||
panic(fmt.Sprintf("Inequality %#x ^ %#x mod %#x \n have %s\n want %s", base, exp, mod, a, b))
|
||||
}
|
||||
return 1
|
||||
}
|
||||
|
||||
// getData returns a slice from the data based on the start and size and pads
|
||||
// up to size with zero's. This function is overflow safe.
|
||||
func getData(data []byte, start uint64, size uint64) []byte {
|
||||
length := uint64(len(data))
|
||||
if start > length {
|
||||
start = length
|
||||
}
|
||||
end := start + size
|
||||
if end > length {
|
||||
end = length
|
||||
}
|
||||
return common.RightPadBytes(data[start:end], int(size))
|
||||
}
|
||||
|
|
@ -228,7 +228,7 @@ func runBenchmark(b *testing.B, t *StateTest) {
|
|||
evm := vm.NewEVM(context, txContext, statedb, config, vmconfig)
|
||||
|
||||
// Create "contract" for sender to cache code analysis.
|
||||
sender := vm.NewContract(vm.AccountRef(msg.From()), vm.AccountRef(msg.From()),
|
||||
sender := vm.NewContract(vm.AccountRef(msg.From), vm.AccountRef(msg.From),
|
||||
nil, 0)
|
||||
|
||||
var (
|
||||
|
|
@ -239,12 +239,12 @@ func runBenchmark(b *testing.B, t *StateTest) {
|
|||
b.ResetTimer()
|
||||
for n := 0; n < b.N; n++ {
|
||||
snapshot := statedb.Snapshot()
|
||||
statedb.Prepare(rules, msg.From(), context.Coinbase, msg.To(), vm.ActivePrecompiles(rules), msg.AccessList())
|
||||
statedb.Prepare(rules, msg.From, context.Coinbase, msg.To, vm.ActivePrecompiles(rules), msg.AccessList)
|
||||
b.StartTimer()
|
||||
start := time.Now()
|
||||
|
||||
// Execute the message.
|
||||
_, leftOverGas, err := evm.Call(sender, *msg.To(), msg.Data(), msg.Gas(), msg.Value())
|
||||
_, leftOverGas, err := evm.Call(sender, *msg.To, msg.Data, msg.GasLimit, msg.Value)
|
||||
if err != nil {
|
||||
b.Error(err)
|
||||
return
|
||||
|
|
@ -253,7 +253,7 @@ func runBenchmark(b *testing.B, t *StateTest) {
|
|||
b.StopTimer()
|
||||
elapsed += uint64(time.Since(start))
|
||||
refund += statedb.GetRefund()
|
||||
gasUsed += msg.Gas() - leftOverGas
|
||||
gasUsed += msg.GasLimit - leftOverGas
|
||||
|
||||
statedb.RevertToSnapshot(snapshot)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -329,7 +329,7 @@ func (t *StateTest) genesis(config *params.ChainConfig) *core.Genesis {
|
|||
return genesis
|
||||
}
|
||||
|
||||
func (tx *stTransaction) toMessage(ps stPostState, baseFee *big.Int) (core.Message, error) {
|
||||
func (tx *stTransaction) toMessage(ps stPostState, baseFee *big.Int) (*core.Message, error) {
|
||||
// Derive sender from private key if present.
|
||||
var from common.Address
|
||||
if len(tx.PrivateKey) > 0 {
|
||||
|
|
@ -397,8 +397,18 @@ func (tx *stTransaction) toMessage(ps stPostState, baseFee *big.Int) (core.Messa
|
|||
return nil, fmt.Errorf("no gas price provided")
|
||||
}
|
||||
|
||||
msg := types.NewMessage(from, to, tx.Nonce, value, gasLimit, gasPrice,
|
||||
tx.MaxFeePerGas, tx.MaxPriorityFeePerGas, data, accessList, false, false)
|
||||
msg := &core.Message{
|
||||
From: from,
|
||||
To: to,
|
||||
Nonce: tx.Nonce,
|
||||
Value: value,
|
||||
GasLimit: gasLimit,
|
||||
GasPrice: gasPrice,
|
||||
GasFeeCap: tx.MaxFeePerGas,
|
||||
GasTipCap: tx.MaxPriorityFeePerGas,
|
||||
Data: data,
|
||||
AccessList: accessList,
|
||||
}
|
||||
return msg, nil
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue