mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-05 12:41:14 +00:00
Merge pull request #296 from XinFinOrg/dev-upgrade-merge-master
Dev upgrade merge master
This commit is contained in:
commit
bb6d797dad
30 changed files with 376 additions and 86 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -54,4 +54,4 @@ go.sum
|
||||||
|
|
||||||
cicd/devnet/terraform/.terraform
|
cicd/devnet/terraform/.terraform
|
||||||
cicd/devnet/.pwd
|
cicd/devnet/.pwd
|
||||||
cicd/devnet/tmp/
|
cicd/devnet/tmp/
|
||||||
|
|
|
||||||
|
|
@ -24,15 +24,6 @@ env:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
include:
|
include:
|
||||||
# TODO: temporary turn off linting to help fix all the tests. We will turn it back on once the branch is stable
|
|
||||||
# - stage: Lint
|
|
||||||
# sudo: false
|
|
||||||
# go: '1.14.x'
|
|
||||||
# git:
|
|
||||||
# submodules: false
|
|
||||||
# script:
|
|
||||||
# - go run build/ci.go lint
|
|
||||||
|
|
||||||
- stage: Tests
|
- stage: Tests
|
||||||
os: linux
|
os: linux
|
||||||
dist: bionic
|
dist: bionic
|
||||||
|
|
|
||||||
14
README.md
14
README.md
|
|
@ -1,4 +1,15 @@
|
||||||
# XDPoSChain
|
# XDPoSChain
|
||||||
|
|
||||||
|
<p align="center">
|
||||||
|
<img src="./assets/images/xinfin-logo.png" />
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p align="center">
|
||||||
|
XinFin XDPoSchain<br/>
|
||||||
|
Enterprise ready hybrid blockchain for global trade and finance
|
||||||
|
</p>
|
||||||
|
<br/>
|
||||||
|
|
||||||
## XinFin Hybrid Blockchain
|
## XinFin Hybrid Blockchain
|
||||||
|
|
||||||
XinFin Hybrid Blockchain is an Enterprise ready Blockchain for global trade and finance
|
XinFin Hybrid Blockchain is an Enterprise ready Blockchain for global trade and finance
|
||||||
|
|
@ -51,5 +62,4 @@ See https://github.com/XinFinOrg/XDPoSChain/tree/dev-upgrade/cicd
|
||||||
|
|
||||||
Simple create a pull request along with proper reasoning, we'll get back to you.
|
Simple create a pull request along with proper reasoning, we'll get back to you.
|
||||||
|
|
||||||
Our Channels : [Telegram Developer Group](https://t.me/XinFinDevelopers) or [Public Slack Group](https://launchpass.com/xinfin-public)
|
Our Channels : [Telegram Developer Group](https://t.me/XinFinDevelopers) or [XDC.Dev](https://xdc.dev)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
EmptyAddress = "0x0000000000000000000000000000000000000000"
|
EmptyAddress = "xdc0000000000000000000000000000000000000000"
|
||||||
EmptyRoot = common.HexToHash("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421")
|
EmptyRoot = common.HexToHash("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,8 +19,11 @@ package abi
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
|
"github.com/XinFinOrg/XDPoSChain/crypto"
|
||||||
)
|
)
|
||||||
|
|
||||||
// The ABI holds information about a contract's context and available
|
// The ABI holds information about a contract's context and available
|
||||||
|
|
@ -144,3 +147,26 @@ func (abi *ABI) MethodById(sigdata []byte) (*Method, error) {
|
||||||
}
|
}
|
||||||
return nil, fmt.Errorf("no method with id: %#x", sigdata[:4])
|
return nil, fmt.Errorf("no method with id: %#x", sigdata[:4])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// revertSelector is a special function selector for revert reason unpacking.
|
||||||
|
var revertSelector = crypto.Keccak256([]byte("Error(string)"))[:4]
|
||||||
|
|
||||||
|
// UnpackRevert resolves the abi-encoded revert reason. According to the solidity
|
||||||
|
// spec https://solidity.readthedocs.io/en/latest/control-structures.html#revert,
|
||||||
|
// the provided revert reason is abi-encoded as if it were a call to a function
|
||||||
|
// `Error(string)`. So it's a special tool for it.
|
||||||
|
func UnpackRevert(data []byte) (string, error) {
|
||||||
|
if len(data) < 4 {
|
||||||
|
return "", errors.New("invalid data for unpacking")
|
||||||
|
}
|
||||||
|
if !bytes.Equal(data[:4], revertSelector) {
|
||||||
|
return "", errors.New("invalid data for unpacking")
|
||||||
|
}
|
||||||
|
typ, _ := NewType("string")
|
||||||
|
unpacked, err := (Arguments{{Type: typ}}).Unpack2(data[4:])
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return unpacked[0].(string), nil
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ package abi
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"reflect"
|
"reflect"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
@ -100,6 +101,17 @@ func (arguments Arguments) Unpack(v interface{}, data []byte) error {
|
||||||
return arguments.unpackAtomic(v, marshalledValues)
|
return arguments.unpackAtomic(v, marshalledValues)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Unpack2 performs the operation hexdata -> Go format.
|
||||||
|
func (arguments Arguments) Unpack2(data []byte) ([]interface{}, error) {
|
||||||
|
if len(data) == 0 {
|
||||||
|
if len(arguments.NonIndexed()) != 0 {
|
||||||
|
return nil, errors.New("abi: attempting to unmarshall an empty string while arguments are expected")
|
||||||
|
}
|
||||||
|
return make([]interface{}, 0), nil
|
||||||
|
}
|
||||||
|
return arguments.UnpackValues(data)
|
||||||
|
}
|
||||||
|
|
||||||
func (arguments Arguments) unpackTuple(v interface{}, marshalledValues []interface{}) error {
|
func (arguments Arguments) unpackTuple(v interface{}, marshalledValues []interface{}) error {
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|
|
||||||
|
|
@ -351,7 +351,7 @@ func (b *SimulatedBackend) EstimateGas(ctx context.Context, call XDPoSChain.Call
|
||||||
|
|
||||||
// callContract implements common code between normal and pending contract calls.
|
// callContract implements common code between normal and pending contract calls.
|
||||||
// state is modified during execution, make sure to copy it if necessary.
|
// state is modified during execution, make sure to copy it if necessary.
|
||||||
func (b *SimulatedBackend) callContract(ctx context.Context, call XDPoSChain.CallMsg, block *types.Block, statedb *state.StateDB) ([]byte, uint64, bool, error) {
|
func (b *SimulatedBackend) callContract(ctx context.Context, call XDPoSChain.CallMsg, block *types.Block, statedb *state.StateDB) (ret []byte, usedGas uint64, failed bool, err error) {
|
||||||
// Ensure message is initialized properly.
|
// Ensure message is initialized properly.
|
||||||
if call.GasPrice == nil {
|
if call.GasPrice == nil {
|
||||||
call.GasPrice = big.NewInt(1)
|
call.GasPrice = big.NewInt(1)
|
||||||
|
|
@ -379,7 +379,8 @@ func (b *SimulatedBackend) callContract(ctx context.Context, call XDPoSChain.Cal
|
||||||
vmenv := vm.NewEVM(evmContext, statedb, nil, b.config, vm.Config{})
|
vmenv := vm.NewEVM(evmContext, statedb, nil, b.config, vm.Config{})
|
||||||
gaspool := new(core.GasPool).AddGas(math.MaxUint64)
|
gaspool := new(core.GasPool).AddGas(math.MaxUint64)
|
||||||
owner := common.Address{}
|
owner := common.Address{}
|
||||||
return core.NewStateTransition(vmenv, msg, gaspool).TransitionDb(owner)
|
ret, usedGas, failed, err, _ = core.NewStateTransition(vmenv, msg, gaspool).TransitionDb(owner)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// SendTransaction updates the pending block to include the given transaction.
|
// SendTransaction updates the pending block to include the given transaction.
|
||||||
|
|
|
||||||
BIN
assets/images/xinfin-logo.png
Normal file
BIN
assets/images/xinfin-logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 11 KiB |
143
cmd/XDC/apothem.go
Normal file
143
cmd/XDC/apothem.go
Normal file
File diff suppressed because one or more lines are too long
|
|
@ -105,5 +105,4 @@ const header = `Please answer these questions before submitting your issue. Than
|
||||||
|
|
||||||
#### What did you see instead?
|
#### What did you see instead?
|
||||||
|
|
||||||
#### System details
|
#### System details`
|
||||||
`
|
|
||||||
|
|
|
||||||
|
|
@ -25,18 +25,17 @@ import (
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/XinFinOrg/XDPoSChain/core/rawdb"
|
|
||||||
"github.com/XinFinOrg/XDPoSChain/metrics"
|
|
||||||
|
|
||||||
"github.com/XinFinOrg/XDPoSChain/cmd/utils"
|
"github.com/XinFinOrg/XDPoSChain/cmd/utils"
|
||||||
"github.com/XinFinOrg/XDPoSChain/common"
|
"github.com/XinFinOrg/XDPoSChain/common"
|
||||||
"github.com/XinFinOrg/XDPoSChain/console"
|
"github.com/XinFinOrg/XDPoSChain/console"
|
||||||
"github.com/XinFinOrg/XDPoSChain/core"
|
"github.com/XinFinOrg/XDPoSChain/core"
|
||||||
|
"github.com/XinFinOrg/XDPoSChain/core/rawdb"
|
||||||
"github.com/XinFinOrg/XDPoSChain/core/state"
|
"github.com/XinFinOrg/XDPoSChain/core/state"
|
||||||
"github.com/XinFinOrg/XDPoSChain/core/types"
|
"github.com/XinFinOrg/XDPoSChain/core/types"
|
||||||
"github.com/XinFinOrg/XDPoSChain/eth/downloader"
|
"github.com/XinFinOrg/XDPoSChain/eth/downloader"
|
||||||
"github.com/XinFinOrg/XDPoSChain/event"
|
"github.com/XinFinOrg/XDPoSChain/event"
|
||||||
"github.com/XinFinOrg/XDPoSChain/log"
|
"github.com/XinFinOrg/XDPoSChain/log"
|
||||||
|
"github.com/XinFinOrg/XDPoSChain/metrics"
|
||||||
"gopkg.in/urfave/cli.v1"
|
"gopkg.in/urfave/cli.v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -49,6 +48,7 @@ var (
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
utils.DataDirFlag,
|
utils.DataDirFlag,
|
||||||
utils.LightModeFlag,
|
utils.LightModeFlag,
|
||||||
|
utils.XDCTestnetFlag,
|
||||||
},
|
},
|
||||||
Category: "BLOCKCHAIN COMMANDS",
|
Category: "BLOCKCHAIN COMMANDS",
|
||||||
Description: `
|
Description: `
|
||||||
|
|
@ -176,19 +176,31 @@ Use "ethereum dump 0" to dump the genesis block.`,
|
||||||
func initGenesis(ctx *cli.Context) error {
|
func initGenesis(ctx *cli.Context) error {
|
||||||
// Make sure we have a valid genesis JSON
|
// Make sure we have a valid genesis JSON
|
||||||
genesisPath := ctx.Args().First()
|
genesisPath := ctx.Args().First()
|
||||||
if len(genesisPath) == 0 {
|
|
||||||
utils.Fatalf("Must supply path to genesis JSON file")
|
|
||||||
}
|
|
||||||
file, err := os.Open(genesisPath)
|
|
||||||
if err != nil {
|
|
||||||
utils.Fatalf("Failed to read genesis file: %v", err)
|
|
||||||
}
|
|
||||||
defer file.Close()
|
|
||||||
|
|
||||||
genesis := new(core.Genesis)
|
genesis := new(core.Genesis)
|
||||||
if err := json.NewDecoder(file).Decode(genesis); err != nil {
|
|
||||||
utils.Fatalf("invalid genesis file: %v", err)
|
if ctx.GlobalBool(utils.XDCTestnetFlag.Name) {
|
||||||
|
if len(genesisPath) > 0 {
|
||||||
|
utils.Fatalf("Flags --apothem and genesis file can't be used at the same time")
|
||||||
|
}
|
||||||
|
err := json.Unmarshal(apothemGenesis, &genesis)
|
||||||
|
if err != nil {
|
||||||
|
utils.Fatalf("invalid genesis json: %v", err)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if len(genesisPath) == 0 {
|
||||||
|
utils.Fatalf("Must supply path to genesis JSON file")
|
||||||
|
}
|
||||||
|
file, err := os.Open(genesisPath)
|
||||||
|
if err != nil {
|
||||||
|
utils.Fatalf("Failed to read genesis file: %v", err)
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
|
||||||
|
if err := json.NewDecoder(file).Decode(genesis); err != nil {
|
||||||
|
utils.Fatalf("invalid genesis file: %v", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Open an initialise both full and light databases
|
// Open an initialise both full and light databases
|
||||||
stack, _ := makeFullNode(ctx)
|
stack, _ := makeFullNode(ctx)
|
||||||
for _, name := range []string{"chaindata", "lightchaindata"} {
|
for _, name := range []string{"chaindata", "lightchaindata"} {
|
||||||
|
|
|
||||||
|
|
@ -160,11 +160,14 @@ func makeConfigNode(ctx *cli.Context) (*node.Node, XDCConfig) {
|
||||||
common.TRC21IssuerSMC = common.TRC21IssuerSMCTestNet
|
common.TRC21IssuerSMC = common.TRC21IssuerSMCTestNet
|
||||||
cfg.Eth.NetworkId = 51
|
cfg.Eth.NetworkId = 51
|
||||||
common.RelayerRegistrationSMC = common.RelayerRegistrationSMCTestnet
|
common.RelayerRegistrationSMC = common.RelayerRegistrationSMCTestnet
|
||||||
common.TIPTRC21Fee = common.TIPXDCXTestnet
|
|
||||||
common.TIPTRC21Fee = common.TIPTRC21FeeTestnet
|
common.TIPTRC21Fee = common.TIPTRC21FeeTestnet
|
||||||
common.TIPXDCXCancellationFee = common.TIPXDCXCancellationFeeTestnet
|
common.TIPXDCXCancellationFee = common.TIPXDCXCancellationFeeTestnet
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ctx.GlobalBool(utils.Enable0xPrefixFlag.Name) {
|
||||||
|
common.Enable0xPrefix = true
|
||||||
|
}
|
||||||
|
|
||||||
// Rewound
|
// Rewound
|
||||||
if rewound := ctx.GlobalInt(utils.RewoundFlag.Name); rewound != 0 {
|
if rewound := ctx.GlobalInt(utils.RewoundFlag.Name); rewound != 0 {
|
||||||
common.Rewound = uint64(rewound)
|
common.Rewound = uint64(rewound)
|
||||||
|
|
|
||||||
|
|
@ -113,6 +113,7 @@ var (
|
||||||
//utils.RinkebyFlag,
|
//utils.RinkebyFlag,
|
||||||
//utils.VMEnableDebugFlag,
|
//utils.VMEnableDebugFlag,
|
||||||
utils.XDCTestnetFlag,
|
utils.XDCTestnetFlag,
|
||||||
|
utils.Enable0xPrefixFlag,
|
||||||
utils.RewoundFlag,
|
utils.RewoundFlag,
|
||||||
utils.NetworkIdFlag,
|
utils.NetworkIdFlag,
|
||||||
utils.RPCCORSDomainFlag,
|
utils.RPCCORSDomainFlag,
|
||||||
|
|
|
||||||
|
|
@ -116,6 +116,10 @@ var (
|
||||||
Usage: "Rollback chain at hash",
|
Usage: "Rollback chain at hash",
|
||||||
Value: "",
|
Value: "",
|
||||||
}
|
}
|
||||||
|
Enable0xPrefixFlag = cli.BoolFlag{
|
||||||
|
Name: "enable-0x-prefix",
|
||||||
|
Usage: "Addres use 0x-prefix (default = false)",
|
||||||
|
}
|
||||||
// General settings
|
// General settings
|
||||||
AnnounceTxsFlag = cli.BoolFlag{
|
AnnounceTxsFlag = cli.BoolFlag{
|
||||||
Name: "announce-txs",
|
Name: "announce-txs",
|
||||||
|
|
|
||||||
|
|
@ -48,6 +48,7 @@ var TIPXDCXCancellationFeeTestnet = big.NewInt(38383838)
|
||||||
|
|
||||||
var TIPXDCXTestnet = big.NewInt(38383838)
|
var TIPXDCXTestnet = big.NewInt(38383838)
|
||||||
var IsTestnet bool = false
|
var IsTestnet bool = false
|
||||||
|
var Enable0xPrefix bool = false
|
||||||
var StoreRewardFolder string
|
var StoreRewardFolder string
|
||||||
var RollbackHash Hash
|
var RollbackHash Hash
|
||||||
var BasePrice = big.NewInt(1000000000000000000) // 1
|
var BasePrice = big.NewInt(1000000000000000000) // 1
|
||||||
|
|
|
||||||
|
|
@ -250,8 +250,11 @@ func (a *Address) Set(other Address) {
|
||||||
// MarshalText returns the hex representation of a.
|
// MarshalText returns the hex representation of a.
|
||||||
func (a Address) MarshalText() ([]byte, error) {
|
func (a Address) MarshalText() ([]byte, error) {
|
||||||
// Handle '0x' or 'xdc' prefix here.
|
// Handle '0x' or 'xdc' prefix here.
|
||||||
// return hexutil.Bytes(a[:]).MarshalText()
|
if (Enable0xPrefix) {
|
||||||
return hexutil.Bytes(a[:]).MarshalXDCText()
|
return hexutil.Bytes(a[:]).MarshalText()
|
||||||
|
} else {
|
||||||
|
return hexutil.Bytes(a[:]).MarshalXDCText()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// UnmarshalText parses a hash in hex syntax.
|
// UnmarshalText parses a hash in hex syntax.
|
||||||
|
|
|
||||||
|
|
@ -57,7 +57,7 @@ func (x *XDPoS_v2) getEpochSwitchInfo(chain consensus.ChainReader, header *types
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
snap, err := x.getSnapshot(chain, header.Number.Uint64(), false)
|
snap, err := x.getSnapshot(chain, h.Number.Uint64(), false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("[getEpochSwitchInfo] Adaptor v2 getSnapshot has error", "err", err)
|
log.Error("[getEpochSwitchInfo] Adaptor v2 getSnapshot has error", "err", err)
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
|
||||||
|
|
@ -184,6 +184,7 @@ func TestAdaptorGetMasternodesV2(t *testing.T) {
|
||||||
|
|
||||||
// block 901 is the first v2 block, and is treated as epoch switch block
|
// block 901 is the first v2 block, and is treated as epoch switch block
|
||||||
err := blockchain.InsertBlock(currentBlock)
|
err := blockchain.InsertBlock(currentBlock)
|
||||||
|
adaptor.Initial(blockchain, currentBlock.Header())
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
masternodes1 := adaptor.GetMasternodes(blockchain, currentBlock.Header())
|
masternodes1 := adaptor.GetMasternodes(blockchain, currentBlock.Header())
|
||||||
assert.Equal(t, 5, len(masternodes1))
|
assert.Equal(t, 5, len(masternodes1))
|
||||||
|
|
@ -216,6 +217,8 @@ func TestGetCurrentEpochSwitchBlock(t *testing.T) {
|
||||||
currentBlock = CreateBlock(blockchain, params.TestXDPoSMockChainConfig, currentBlock, blockNum, 1, blockCoinBase, signer, signFn, nil, nil, "")
|
currentBlock = CreateBlock(blockchain, params.TestXDPoSMockChainConfig, currentBlock, blockNum, 1, blockCoinBase, signer, signFn, nil, nil, "")
|
||||||
err = blockchain.InsertBlock(currentBlock)
|
err = blockchain.InsertBlock(currentBlock)
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
|
adaptor.Initial(blockchain, currentBlock.Header())
|
||||||
|
|
||||||
currentCheckpointNumber, epochNum, err = adaptor.GetCurrentEpochSwitchBlock(blockchain, currentBlock.Number())
|
currentCheckpointNumber, epochNum, err = adaptor.GetCurrentEpochSwitchBlock(blockchain, currentBlock.Number())
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
assert.Equal(t, uint64(901), currentCheckpointNumber)
|
assert.Equal(t, uint64(901), currentCheckpointNumber)
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,8 @@ func TestIsYourTurnConsensusV2(t *testing.T) {
|
||||||
currentBlockHeader.Time = big.NewInt(time.Now().Unix())
|
currentBlockHeader.Time = big.NewInt(time.Now().Unix())
|
||||||
err := blockchain.InsertBlock(currentBlock)
|
err := blockchain.InsertBlock(currentBlock)
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
|
adaptor.Initial(blockchain, currentBlockHeader)
|
||||||
|
|
||||||
// Less then Mine Period
|
// Less then Mine Period
|
||||||
isYourTurn, err := adaptor.YourTurn(blockchain, currentBlockHeader, common.HexToAddress("xdc0D3ab14BBaD3D99F4203bd7a11aCB94882050E7e"))
|
isYourTurn, err := adaptor.YourTurn(blockchain, currentBlockHeader, common.HexToAddress("xdc0D3ab14BBaD3D99F4203bd7a11aCB94882050E7e"))
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
|
|
|
||||||
|
|
@ -409,7 +409,7 @@ func ApplyTransaction(config *params.ChainConfig, tokensFee map[common.Address]*
|
||||||
// End Bypass blacklist address
|
// End Bypass blacklist address
|
||||||
|
|
||||||
// Apply the transaction to the current state (included in the env)
|
// Apply the transaction to the current state (included in the env)
|
||||||
_, gas, failed, err := ApplyMessage(vmenv, msg, gp, coinbaseOwner)
|
_, gas, failed, err, _ := ApplyMessage(vmenv, msg, gp, coinbaseOwner)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, 0, err, false
|
return nil, 0, err, false
|
||||||
|
|
|
||||||
|
|
@ -129,7 +129,7 @@ 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
|
// 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
|
// indicates a core error meaning that the message would always fail for that particular
|
||||||
// state and would never be accepted within a block.
|
// state and would never be accepted within a block.
|
||||||
func ApplyMessage(evm *vm.EVM, msg Message, gp *GasPool, owner common.Address) ([]byte, uint64, bool, error) {
|
func ApplyMessage(evm *vm.EVM, msg Message, gp *GasPool, owner common.Address) ([]byte, uint64, bool, error, error) {
|
||||||
return NewStateTransition(evm, msg, gp).TransitionDb(owner)
|
return NewStateTransition(evm, msg, gp).TransitionDb(owner)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -215,7 +215,7 @@ func (st *StateTransition) preCheck() error {
|
||||||
// TransitionDb will transition the state by applying the current message and
|
// TransitionDb will transition the state by applying the current message and
|
||||||
// returning the result including the the used gas. It returns an error if it
|
// returning the result including the the used gas. It returns an error if it
|
||||||
// failed. An error indicates a consensus issue.
|
// failed. An error indicates a consensus issue.
|
||||||
func (st *StateTransition) TransitionDb(owner common.Address) (ret []byte, usedGas uint64, failed bool, err error) {
|
func (st *StateTransition) TransitionDb(owner common.Address) (ret []byte, usedGas uint64, failed bool, err error, vmErr error) {
|
||||||
if err = st.preCheck(); err != nil {
|
if err = st.preCheck(); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -228,10 +228,10 @@ func (st *StateTransition) TransitionDb(owner common.Address) (ret []byte, usedG
|
||||||
// Pay intrinsic gas
|
// Pay intrinsic gas
|
||||||
gas, err := IntrinsicGas(st.data, contractCreation, homestead)
|
gas, err := IntrinsicGas(st.data, contractCreation, homestead)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, 0, false, err
|
return nil, 0, false, err, nil
|
||||||
}
|
}
|
||||||
if err = st.useGas(gas); err != nil {
|
if err = st.useGas(gas); err != nil {
|
||||||
return nil, 0, false, err
|
return nil, 0, false, err, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|
@ -261,7 +261,7 @@ func (st *StateTransition) TransitionDb(owner common.Address) (ret []byte, usedG
|
||||||
// sufficient balance to make the transfer happen. The first
|
// sufficient balance to make the transfer happen. The first
|
||||||
// balance transfer may never fail.
|
// balance transfer may never fail.
|
||||||
if vmerr == vm.ErrInsufficientBalance {
|
if vmerr == vm.ErrInsufficientBalance {
|
||||||
return nil, 0, false, vmerr
|
return nil, 0, false, vmerr, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
st.refundGas()
|
st.refundGas()
|
||||||
|
|
@ -274,7 +274,7 @@ func (st *StateTransition) TransitionDb(owner common.Address) (ret []byte, usedG
|
||||||
st.state.AddBalance(st.evm.Coinbase, new(big.Int).Mul(new(big.Int).SetUint64(st.gasUsed()), st.gasPrice))
|
st.state.AddBalance(st.evm.Coinbase, new(big.Int).Mul(new(big.Int).SetUint64(st.gasUsed()), st.gasPrice))
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret, st.gasUsed(), vmerr != nil, err
|
return ret, st.gasUsed(), vmerr != nil, err, vmerr
|
||||||
}
|
}
|
||||||
|
|
||||||
func (st *StateTransition) refundGas() {
|
func (st *StateTransition) refundGas() {
|
||||||
|
|
|
||||||
|
|
@ -112,7 +112,7 @@ func CallContractWithState(call ethereum.CallMsg, chain consensus.ChainContext,
|
||||||
vmenv := vm.NewEVM(evmContext, statedb, nil, chain.Config(), vm.Config{})
|
vmenv := vm.NewEVM(evmContext, statedb, nil, chain.Config(), vm.Config{})
|
||||||
gaspool := new(GasPool).AddGas(1000000)
|
gaspool := new(GasPool).AddGas(1000000)
|
||||||
owner := common.Address{}
|
owner := common.Address{}
|
||||||
rval, _, _, err := NewStateTransition(vmenv, msg, gaspool).TransitionDb(owner)
|
rval, _, _, err, _ := NewStateTransition(vmenv, msg, gaspool).TransitionDb(owner)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -726,3 +726,5 @@ func (m Message) Gas() uint64 { return m.gasLimit }
|
||||||
func (m Message) Nonce() uint64 { return m.nonce }
|
func (m Message) Nonce() uint64 { return m.nonce }
|
||||||
func (m Message) Data() []byte { return m.data }
|
func (m Message) Data() []byte { return m.data }
|
||||||
func (m Message) CheckNonce() bool { return m.checkNonce }
|
func (m Message) CheckNonce() bool { return m.checkNonce }
|
||||||
|
|
||||||
|
func (m *Message) SetNonce(nonce uint64) { m.nonce = nonce }
|
||||||
|
|
|
||||||
|
|
@ -474,11 +474,13 @@ func (api *PrivateDebugAPI) traceBlock(ctx context.Context, block *types.Block,
|
||||||
}
|
}
|
||||||
// Generate the next state snapshot fast without tracing
|
// Generate the next state snapshot fast without tracing
|
||||||
msg, _ := tx.AsMessage(signer, balacne, block.Number())
|
msg, _ := tx.AsMessage(signer, balacne, block.Number())
|
||||||
|
// Set nonce to fix issue #256
|
||||||
|
msg.SetNonce(statedb.GetNonce(*tx.From()))
|
||||||
vmctx := core.NewEVMContext(msg, block.Header(), api.eth.blockchain, nil)
|
vmctx := core.NewEVMContext(msg, block.Header(), api.eth.blockchain, nil)
|
||||||
|
|
||||||
vmenv := vm.NewEVM(vmctx, statedb, XDCxState, api.config, vm.Config{})
|
vmenv := vm.NewEVM(vmctx, statedb, XDCxState, api.config, vm.Config{})
|
||||||
owner := common.Address{}
|
owner := common.Address{}
|
||||||
if _, _, _, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(msg.Gas()), owner); err != nil {
|
if _, _, _, err, _ := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(msg.Gas()), owner); err != nil {
|
||||||
failed = err
|
failed = err
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
@ -634,7 +636,7 @@ func (api *PrivateDebugAPI) traceTx(ctx context.Context, message core.Message, v
|
||||||
vmenv := vm.NewEVM(vmctx, statedb, nil, api.config, vm.Config{Debug: true, Tracer: tracer})
|
vmenv := vm.NewEVM(vmctx, statedb, nil, api.config, vm.Config{Debug: true, Tracer: tracer})
|
||||||
|
|
||||||
owner := common.Address{}
|
owner := common.Address{}
|
||||||
ret, gas, failed, err := core.ApplyMessage(vmenv, message, new(core.GasPool).AddGas(message.Gas()), owner)
|
ret, gas, failed, err, _ := core.ApplyMessage(vmenv, message, new(core.GasPool).AddGas(message.Gas()), owner)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("tracing failed: %v", err)
|
return nil, fmt.Errorf("tracing failed: %v", err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -238,7 +238,7 @@ func AttachConsensusV1Hooks(adaptor *XDPoS.XDPoS, bc *core.BlockChain, chainConf
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if address.String() != "0x0000000000000000000000000000000000000000" {
|
if address.String() != "xdc0000000000000000000000000000000000000000" {
|
||||||
candidates = append(candidates, utils.Masternode{Address: address, Stake: v})
|
candidates = append(candidates, utils.Masternode{Address: address, Stake: v})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,13 @@ import (
|
||||||
"crypto/ecdsa"
|
"crypto/ecdsa"
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"io/ioutil"
|
||||||
|
"math/big"
|
||||||
|
"path/filepath"
|
||||||
|
"reflect"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
|
||||||
"github.com/XinFinOrg/XDPoSChain/common"
|
"github.com/XinFinOrg/XDPoSChain/common"
|
||||||
"github.com/XinFinOrg/XDPoSChain/common/hexutil"
|
"github.com/XinFinOrg/XDPoSChain/common/hexutil"
|
||||||
"github.com/XinFinOrg/XDPoSChain/common/math"
|
"github.com/XinFinOrg/XDPoSChain/common/math"
|
||||||
|
|
@ -31,12 +38,6 @@ import (
|
||||||
"github.com/XinFinOrg/XDPoSChain/params"
|
"github.com/XinFinOrg/XDPoSChain/params"
|
||||||
"github.com/XinFinOrg/XDPoSChain/rlp"
|
"github.com/XinFinOrg/XDPoSChain/rlp"
|
||||||
"github.com/XinFinOrg/XDPoSChain/tests"
|
"github.com/XinFinOrg/XDPoSChain/tests"
|
||||||
"io/ioutil"
|
|
||||||
"math/big"
|
|
||||||
"path/filepath"
|
|
||||||
"reflect"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// To generate a new callTracer test, copy paste the makeTest method below into
|
// To generate a new callTracer test, copy paste the makeTest method below into
|
||||||
|
|
@ -183,7 +184,7 @@ func TestPrestateTracerCreate2(t *testing.T) {
|
||||||
t.Fatalf("failed to prepare transaction for tracing: %v", err)
|
t.Fatalf("failed to prepare transaction for tracing: %v", err)
|
||||||
}
|
}
|
||||||
st := core.NewStateTransition(evm, msg, new(core.GasPool).AddGas(tx.Gas()))
|
st := core.NewStateTransition(evm, msg, new(core.GasPool).AddGas(tx.Gas()))
|
||||||
if _, _, _, err = st.TransitionDb(common.Address{}); err != nil {
|
if _, _, _, err, _ = st.TransitionDb(common.Address{}); err != nil {
|
||||||
t.Fatalf("failed to execute transaction: %v", err)
|
t.Fatalf("failed to execute transaction: %v", err)
|
||||||
}
|
}
|
||||||
// Retrieve the trace result and compare against the etalon
|
// Retrieve the trace result and compare against the etalon
|
||||||
|
|
@ -258,7 +259,7 @@ func TestCallTracer(t *testing.T) {
|
||||||
t.Fatalf("failed to prepare transaction for tracing: %v", err)
|
t.Fatalf("failed to prepare transaction for tracing: %v", err)
|
||||||
}
|
}
|
||||||
st := core.NewStateTransition(evm, msg, new(core.GasPool).AddGas(tx.Gas()))
|
st := core.NewStateTransition(evm, msg, new(core.GasPool).AddGas(tx.Gas()))
|
||||||
if _, _, _, err = st.TransitionDb(common.Address{}); err != nil {
|
if _, _, _, err, _ = st.TransitionDb(common.Address{}); err != nil {
|
||||||
t.Fatalf("failed to execute transaction: %v", err)
|
t.Fatalf("failed to execute transaction: %v", err)
|
||||||
}
|
}
|
||||||
// Retrieve the trace result and compare against the etalon
|
// Retrieve the trace result and compare against the etalon
|
||||||
|
|
|
||||||
|
|
@ -26,17 +26,16 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/XinFinOrg/XDPoSChain/XDCxlending/lendingstate"
|
|
||||||
"github.com/XinFinOrg/XDPoSChain/consensus"
|
|
||||||
|
|
||||||
"github.com/XinFinOrg/XDPoSChain/XDCx/tradingstate"
|
"github.com/XinFinOrg/XDPoSChain/XDCx/tradingstate"
|
||||||
|
"github.com/XinFinOrg/XDPoSChain/XDCxlending/lendingstate"
|
||||||
"github.com/XinFinOrg/XDPoSChain/accounts"
|
"github.com/XinFinOrg/XDPoSChain/accounts"
|
||||||
|
"github.com/XinFinOrg/XDPoSChain/accounts/abi"
|
||||||
"github.com/XinFinOrg/XDPoSChain/accounts/abi/bind"
|
"github.com/XinFinOrg/XDPoSChain/accounts/abi/bind"
|
||||||
"github.com/XinFinOrg/XDPoSChain/accounts/keystore"
|
"github.com/XinFinOrg/XDPoSChain/accounts/keystore"
|
||||||
"github.com/XinFinOrg/XDPoSChain/common"
|
"github.com/XinFinOrg/XDPoSChain/common"
|
||||||
"github.com/XinFinOrg/XDPoSChain/common/hexutil"
|
"github.com/XinFinOrg/XDPoSChain/common/hexutil"
|
||||||
"github.com/XinFinOrg/XDPoSChain/common/math"
|
"github.com/XinFinOrg/XDPoSChain/common/math"
|
||||||
|
"github.com/XinFinOrg/XDPoSChain/consensus"
|
||||||
"github.com/XinFinOrg/XDPoSChain/consensus/XDPoS"
|
"github.com/XinFinOrg/XDPoSChain/consensus/XDPoS"
|
||||||
"github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/utils"
|
"github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/utils"
|
||||||
"github.com/XinFinOrg/XDPoSChain/consensus/ethash"
|
"github.com/XinFinOrg/XDPoSChain/consensus/ethash"
|
||||||
|
|
@ -757,7 +756,7 @@ func (s *PublicBlockChainAPI) GetCandidateStatus(ctx context.Context, coinbaseAd
|
||||||
candidatesAddresses := state.GetCandidates(statedb)
|
candidatesAddresses := state.GetCandidates(statedb)
|
||||||
for _, address := range candidatesAddresses {
|
for _, address := range candidatesAddresses {
|
||||||
v := state.GetCandidateCap(statedb, address)
|
v := state.GetCandidateCap(statedb, address)
|
||||||
if address.String() != "0x0000000000000000000000000000000000000000" {
|
if address.String() != "xdc0000000000000000000000000000000000000000" {
|
||||||
candidates = append(candidates, utils.Masternode{Address: address, Stake: v})
|
candidates = append(candidates, utils.Masternode{Address: address, Stake: v})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -883,7 +882,7 @@ func (s *PublicBlockChainAPI) GetCandidates(ctx context.Context, epoch rpc.Epoch
|
||||||
candidatesAddresses := state.GetCandidates(statedb)
|
candidatesAddresses := state.GetCandidates(statedb)
|
||||||
for _, address := range candidatesAddresses {
|
for _, address := range candidatesAddresses {
|
||||||
v := state.GetCandidateCap(statedb, address)
|
v := state.GetCandidateCap(statedb, address)
|
||||||
if address.String() != "0x0000000000000000000000000000000000000000" {
|
if address.String() != "xdc0000000000000000000000000000000000000000" {
|
||||||
candidates = append(candidates, utils.Masternode{Address: address, Stake: v})
|
candidates = append(candidates, utils.Masternode{Address: address, Stake: v})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1017,7 +1016,7 @@ func (s *PublicBlockChainAPI) getCandidatesFromSmartContract() ([]utils.Masterno
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return []utils.Masternode{}, err
|
return []utils.Masternode{}, err
|
||||||
}
|
}
|
||||||
if candidate.String() != "0x0000000000000000000000000000000000000000" {
|
if candidate.String() != "xdc0000000000000000000000000000000000000000" {
|
||||||
candidatesWithStakeInfo = append(candidatesWithStakeInfo, utils.Masternode{Address: candidate, Stake: v})
|
candidatesWithStakeInfo = append(candidatesWithStakeInfo, utils.Masternode{Address: candidate, Stake: v})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1040,12 +1039,12 @@ type CallArgs struct {
|
||||||
Data hexutil.Bytes `json:"data"`
|
Data hexutil.Bytes `json:"data"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *PublicBlockChainAPI) doCall(ctx context.Context, args CallArgs, blockNr rpc.BlockNumber, vmCfg vm.Config, timeout time.Duration) ([]byte, uint64, bool, error) {
|
func (s *PublicBlockChainAPI) doCall(ctx context.Context, args CallArgs, blockNr rpc.BlockNumber, vmCfg vm.Config, timeout time.Duration) ([]byte, uint64, bool, error, error) {
|
||||||
defer func(start time.Time) { log.Debug("Executing EVM call finished", "runtime", time.Since(start)) }(time.Now())
|
defer func(start time.Time) { log.Debug("Executing EVM call finished", "runtime", time.Since(start)) }(time.Now())
|
||||||
|
|
||||||
statedb, header, err := s.b.StateAndHeaderByNumber(ctx, blockNr)
|
statedb, header, err := s.b.StateAndHeaderByNumber(ctx, blockNr)
|
||||||
if statedb == nil || err != nil {
|
if statedb == nil || err != nil {
|
||||||
return nil, 0, false, err
|
return nil, 0, false, err, nil
|
||||||
}
|
}
|
||||||
// Set sender address or use a default if none specified
|
// Set sender address or use a default if none specified
|
||||||
addr := args.From
|
addr := args.From
|
||||||
|
|
@ -1083,20 +1082,20 @@ func (s *PublicBlockChainAPI) doCall(ctx context.Context, args CallArgs, blockNr
|
||||||
|
|
||||||
block, err := s.b.BlockByNumber(ctx, blockNr)
|
block, err := s.b.BlockByNumber(ctx, blockNr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, 0, false, err
|
return nil, 0, false, err, nil
|
||||||
}
|
}
|
||||||
author, err := s.b.GetEngine().Author(block.Header())
|
author, err := s.b.GetEngine().Author(block.Header())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, 0, false, err
|
return nil, 0, false, err, nil
|
||||||
}
|
}
|
||||||
XDCxState, err := s.b.XDCxService().GetTradingState(block, author)
|
XDCxState, err := s.b.XDCxService().GetTradingState(block, author)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, 0, false, err
|
return nil, 0, false, err, nil
|
||||||
}
|
}
|
||||||
// Get a new instance of the EVM.
|
// Get a new instance of the EVM.
|
||||||
evm, vmError, err := s.b.GetEVM(ctx, msg, statedb, XDCxState, header, vmCfg)
|
evm, vmError, err := s.b.GetEVM(ctx, msg, statedb, XDCxState, header, vmCfg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, 0, false, err
|
return nil, 0, false, err, nil
|
||||||
}
|
}
|
||||||
// Wait for the context to be done and cancel the evm. Even if the
|
// Wait for the context to be done and cancel the evm. Even if the
|
||||||
// EVM has finished, cancelling may be done (repeatedly)
|
// EVM has finished, cancelling may be done (repeatedly)
|
||||||
|
|
@ -1109,18 +1108,64 @@ func (s *PublicBlockChainAPI) doCall(ctx context.Context, args CallArgs, blockNr
|
||||||
// and apply the message.
|
// and apply the message.
|
||||||
gp := new(core.GasPool).AddGas(math.MaxUint64)
|
gp := new(core.GasPool).AddGas(math.MaxUint64)
|
||||||
owner := common.Address{}
|
owner := common.Address{}
|
||||||
res, gas, failed, err := core.ApplyMessage(evm, msg, gp, owner)
|
res, gas, failed, err, vmErr := core.ApplyMessage(evm, msg, gp, owner)
|
||||||
if err := vmError(); err != nil {
|
if err := vmError(); err != nil {
|
||||||
return nil, 0, false, err
|
return nil, 0, false, err, nil
|
||||||
}
|
}
|
||||||
return res, gas, failed, err
|
|
||||||
|
// If the timer caused an abort, return an appropriate error message
|
||||||
|
if evm.Cancelled() {
|
||||||
|
return nil, 0, false, fmt.Errorf("execution aborted (timeout = %v)", timeout), nil
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return res, 0, false, fmt.Errorf("err: %w (supplied gas %d)", err, msg.Gas()), nil
|
||||||
|
}
|
||||||
|
return res, gas, failed, err, vmErr
|
||||||
|
}
|
||||||
|
|
||||||
|
func newRevertError(res []byte) *revertError {
|
||||||
|
reason, errUnpack := abi.UnpackRevert(res)
|
||||||
|
err := errors.New("execution reverted")
|
||||||
|
if errUnpack == nil {
|
||||||
|
err = fmt.Errorf("execution reverted: %v", reason)
|
||||||
|
}
|
||||||
|
return &revertError{
|
||||||
|
error: err,
|
||||||
|
reason: hexutil.Encode(res),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// revertError is an API error that encompasses an EVM revertal with JSON error
|
||||||
|
// code and a binary data blob.
|
||||||
|
type revertError struct {
|
||||||
|
error
|
||||||
|
reason string // revert reason hex encoded
|
||||||
|
}
|
||||||
|
|
||||||
|
// ErrorCode returns the JSON error code for a revertal.
|
||||||
|
// See: https://github.com/ethereum/wiki/wiki/JSON-RPC-Error-Codes-Improvement-Proposal
|
||||||
|
func (e *revertError) ErrorCode() int {
|
||||||
|
return 3
|
||||||
|
}
|
||||||
|
|
||||||
|
// ErrorData returns the hex encoded revert reason.
|
||||||
|
func (e *revertError) ErrorData() interface{} {
|
||||||
|
return e.reason
|
||||||
}
|
}
|
||||||
|
|
||||||
// Call executes the given transaction on the state for the given block number.
|
// Call executes the given transaction on the state for the given block number.
|
||||||
// It doesn't make and changes in the state/blockchain and is useful to execute and retrieve values.
|
// It doesn't make and changes in the state/blockchain and is useful to execute and retrieve values.
|
||||||
func (s *PublicBlockChainAPI) Call(ctx context.Context, args CallArgs, blockNr rpc.BlockNumber) (hexutil.Bytes, error) {
|
func (s *PublicBlockChainAPI) Call(ctx context.Context, args CallArgs, blockNr rpc.BlockNumber) (hexutil.Bytes, error) {
|
||||||
result, _, _, err := s.doCall(ctx, args, blockNr, vm.Config{}, 5*time.Second)
|
result, _, failed, err, vmErr := s.doCall(ctx, args, blockNr, vm.Config{}, 5*time.Second)
|
||||||
return (hexutil.Bytes)(result), err
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
// If the result contains a revert reason, try to unpack and return it.
|
||||||
|
if failed && len(result) > 0 {
|
||||||
|
return nil, newRevertError(result)
|
||||||
|
}
|
||||||
|
|
||||||
|
return (hexutil.Bytes)(result), vmErr
|
||||||
}
|
}
|
||||||
|
|
||||||
// EstimateGas returns an estimate of the amount of gas needed to execute the
|
// EstimateGas returns an estimate of the amount of gas needed to execute the
|
||||||
|
|
@ -1145,29 +1190,58 @@ func (s *PublicBlockChainAPI) EstimateGas(ctx context.Context, args CallArgs) (h
|
||||||
cap = hi
|
cap = hi
|
||||||
|
|
||||||
// Create a helper to check if a gas allowance results in an executable transaction
|
// Create a helper to check if a gas allowance results in an executable transaction
|
||||||
executable := func(gas uint64) bool {
|
executable := func(gas uint64) (bool, []byte, error, error) {
|
||||||
args.Gas = hexutil.Uint64(gas)
|
args.Gas = hexutil.Uint64(gas)
|
||||||
|
|
||||||
_, _, failed, err := s.doCall(ctx, args, rpc.LatestBlockNumber, vm.Config{}, 0)
|
res, _, failed, err, vmErr := s.doCall(ctx, args, rpc.LatestBlockNumber, vm.Config{}, 0)
|
||||||
if err != nil || failed {
|
if err != nil {
|
||||||
log.Warn("[EstimateGas] api", "err", err)
|
if errors.Is(err, core.ErrIntrinsicGas) {
|
||||||
return false
|
return false, nil, nil, nil // Special case, raise gas limit
|
||||||
|
}
|
||||||
|
return false, nil, err, nil // Bail out
|
||||||
}
|
}
|
||||||
return true
|
if failed {
|
||||||
|
return false, res, nil, vmErr
|
||||||
|
}
|
||||||
|
|
||||||
|
return true, nil, nil, nil
|
||||||
}
|
}
|
||||||
// Execute the binary search and hone in on an executable gas limit
|
// Execute the binary search and hone in on an executable gas limit
|
||||||
for lo+1 < hi {
|
for lo+1 < hi {
|
||||||
mid := (hi + lo) / 2
|
mid := (hi + lo) / 2
|
||||||
if !executable(mid) {
|
ok, _, err, _ := executable(mid)
|
||||||
|
|
||||||
|
// If the error is not nil(consensus error), it means the provided message
|
||||||
|
// call or transaction will never be accepted no matter how much gas it is
|
||||||
|
// assigned. Return the error directly, don't struggle any more.
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if !ok {
|
||||||
lo = mid
|
lo = mid
|
||||||
} else {
|
} else {
|
||||||
hi = mid
|
hi = mid
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reject the transaction as invalid if it still fails at the highest allowance
|
// Reject the transaction as invalid if it still fails at the highest allowance
|
||||||
if hi == cap {
|
if hi == cap {
|
||||||
if !executable(hi) {
|
ok, res, err, vmErr := executable(hi)
|
||||||
return 0, fmt.Errorf("gas required exceeds allowance or always failing transaction")
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
if vmErr != vm.ErrOutOfGas {
|
||||||
|
if len(res) > 0 {
|
||||||
|
return 0, newRevertError(res)
|
||||||
|
}
|
||||||
|
return 0, vmErr
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise, the specified gas cap is too low
|
||||||
|
return 0, fmt.Errorf("gas required exceeds allowance (%d)", cap)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return hexutil.Uint64(hi), nil
|
return hexutil.Uint64(hi), nil
|
||||||
|
|
|
||||||
|
|
@ -141,7 +141,7 @@ func odrContractCall(ctx context.Context, db ethdb.Database, config *params.Chai
|
||||||
//vmenv := core.NewEnv(statedb, config, bc, msg, header, vm.Config{})
|
//vmenv := core.NewEnv(statedb, config, bc, msg, header, vm.Config{})
|
||||||
gp := new(core.GasPool).AddGas(math.MaxUint64)
|
gp := new(core.GasPool).AddGas(math.MaxUint64)
|
||||||
owner := common.Address{}
|
owner := common.Address{}
|
||||||
ret, _, _, _ := core.ApplyMessage(vmenv, msg, gp, owner)
|
ret, _, _, _, _ := core.ApplyMessage(vmenv, msg, gp, owner)
|
||||||
res = append(res, ret...)
|
res = append(res, ret...)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -158,7 +158,7 @@ func odrContractCall(ctx context.Context, db ethdb.Database, config *params.Chai
|
||||||
vmenv := vm.NewEVM(context, statedb, nil, config, vm.Config{})
|
vmenv := vm.NewEVM(context, statedb, nil, config, vm.Config{})
|
||||||
gp := new(core.GasPool).AddGas(math.MaxUint64)
|
gp := new(core.GasPool).AddGas(math.MaxUint64)
|
||||||
owner := common.Address{}
|
owner := common.Address{}
|
||||||
ret, _, _, _ := core.ApplyMessage(vmenv, msg, gp, owner)
|
ret, _, _, _, _ := core.ApplyMessage(vmenv, msg, gp, owner)
|
||||||
if statedb.Error() == nil {
|
if statedb.Error() == nil {
|
||||||
res = append(res, ret...)
|
res = append(res, ret...)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -188,7 +188,7 @@ func odrContractCall(ctx context.Context, db ethdb.Database, bc *core.BlockChain
|
||||||
vmenv := vm.NewEVM(context, st, nil, config, vm.Config{})
|
vmenv := vm.NewEVM(context, st, nil, config, vm.Config{})
|
||||||
gp := new(core.GasPool).AddGas(math.MaxUint64)
|
gp := new(core.GasPool).AddGas(math.MaxUint64)
|
||||||
owner := common.Address{}
|
owner := common.Address{}
|
||||||
ret, _, _, _ := core.ApplyMessage(vmenv, msg, gp, owner)
|
ret, _, _, _, _ := core.ApplyMessage(vmenv, msg, gp, owner)
|
||||||
res = append(res, ret...)
|
res = append(res, ret...)
|
||||||
if st.Error() != nil {
|
if st.Error() != nil {
|
||||||
return res, st.Error()
|
return res, st.Error()
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,6 @@ import (
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/XinFinOrg/XDPoSChain/core/rawdb"
|
|
||||||
"math/big"
|
"math/big"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
|
@ -28,6 +27,7 @@ import (
|
||||||
"github.com/XinFinOrg/XDPoSChain/common/hexutil"
|
"github.com/XinFinOrg/XDPoSChain/common/hexutil"
|
||||||
"github.com/XinFinOrg/XDPoSChain/common/math"
|
"github.com/XinFinOrg/XDPoSChain/common/math"
|
||||||
"github.com/XinFinOrg/XDPoSChain/core"
|
"github.com/XinFinOrg/XDPoSChain/core"
|
||||||
|
"github.com/XinFinOrg/XDPoSChain/core/rawdb"
|
||||||
"github.com/XinFinOrg/XDPoSChain/core/state"
|
"github.com/XinFinOrg/XDPoSChain/core/state"
|
||||||
"github.com/XinFinOrg/XDPoSChain/core/types"
|
"github.com/XinFinOrg/XDPoSChain/core/types"
|
||||||
"github.com/XinFinOrg/XDPoSChain/core/vm"
|
"github.com/XinFinOrg/XDPoSChain/core/vm"
|
||||||
|
|
@ -144,7 +144,7 @@ func (t *StateTest) Run(subtest StateSubtest, vmconfig vm.Config) (*state.StateD
|
||||||
snapshot := statedb.Snapshot()
|
snapshot := statedb.Snapshot()
|
||||||
|
|
||||||
coinbase := &t.json.Env.Coinbase
|
coinbase := &t.json.Env.Coinbase
|
||||||
if _, _, _, err := core.ApplyMessage(evm, msg, gaspool, *coinbase); err != nil {
|
if _, _, _, err, _ := core.ApplyMessage(evm, msg, gaspool, *coinbase); err != nil {
|
||||||
statedb.RevertToSnapshot(snapshot)
|
statedb.RevertToSnapshot(snapshot)
|
||||||
}
|
}
|
||||||
if logs := rlpHash(statedb.Logs()); logs != common.Hash(post.Logs) {
|
if logs := rlpHash(statedb.Logs()); logs != common.Hash(post.Logs) {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue