Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions action/blob_data.go
Original file line number Diff line number Diff line change
Expand Up @@ -155,8 +155,8 @@ func (tx *BlobTxData) SanityCheck() error {
if len(tx.blobHashes) == 0 {
return errors.New("blobless blob transaction")
}
if permitted := params.MaxBlobGasPerBlock / params.BlobTxBlobGasPerBlob; len(tx.blobHashes) > permitted {
return errors.Errorf("too many blobs in transaction: have %d, permitted %d", len(tx.blobHashes), params.MaxBlobGasPerBlock/params.BlobTxBlobGasPerBlob)
if permitted := MaxBlobGasPerBlock / params.BlobTxBlobGasPerBlob; len(tx.blobHashes) > permitted {
return errors.Errorf("too many blobs in transaction: have %d, permitted %d", len(tx.blobHashes), MaxBlobGasPerBlock/params.BlobTxBlobGasPerBlob)
}
return nil
}
Expand Down Expand Up @@ -192,7 +192,7 @@ func verifySidecar(sidecar *types.BlobTxSidecar, hashes []common.Hash) error {
// Blob commitments match with the hashes in the transaction, verify the
// blobs themselves via KZG
for i := range sidecar.Blobs {
if err := kzg4844.VerifyBlobProof(sidecar.Blobs[i], sidecar.Commitments[i], sidecar.Proofs[i]); err != nil {
if err := kzg4844.VerifyBlobProof(&sidecar.Blobs[i], sidecar.Commitments[i], sidecar.Proofs[i]); err != nil {
return errors.Errorf("invalid blob %d: %v", i, err)
}
}
Expand Down
4 changes: 2 additions & 2 deletions action/blob_data_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,14 +132,14 @@ func TestBlobTxData(t *testing.T) {
}

var (
testBlob = kzg4844.Blob{1, 2, 3, 4}
testBlob = &kzg4844.Blob{1, 2, 3, 4}
testBlobCommit = MustNoErrorV(kzg4844.BlobToCommitment(testBlob))
testBlobProof = MustNoErrorV(kzg4844.ComputeBlobProof(testBlob, testBlobCommit))
)

func createTestBlobTxData() *BlobTxData {
sidecar := &types.BlobTxSidecar{
Blobs: []kzg4844.Blob{testBlob},
Blobs: []kzg4844.Blob{*testBlob},
Commitments: []kzg4844.Commitment{testBlobCommit},
Proofs: []kzg4844.Proof{testBlobProof},
}
Expand Down
2 changes: 1 addition & 1 deletion action/builder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ func TestEthTxUtils(t *testing.T) {
var (
signer1, _ = NewEthSigner(iotextypes.Encoding_ETHEREUM_EIP155, chainID)
sig1, _ = sk1.Sign(tx.Hash().Bytes())
signer2 = types.NewCancunSigner(big.NewInt(int64(chainID)))
signer2 = types.NewPragueSigner(big.NewInt(int64(chainID)))
sig2, _ = ethercrypto.Sign(tx.Hash().Bytes(), sk2)
)
r.Equal(signer1, signer2)
Expand Down
3 changes: 2 additions & 1 deletion action/envelope.go
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,8 @@ func (elp *envelope) Size() uint32 {
func (elp *envelope) Action() Action { return elp.payload }

// ToEthTx converts to Ethereum tx
func (elp *envelope) ToEthTx(evmNetworkID uint32, encoding iotextypes.Encoding) (*types.Transaction, error) {
// TODO: remove unused parameters
func (elp *envelope) ToEthTx(_ uint32, _ iotextypes.Encoding) (*types.Transaction, error) {
tx, ok := elp.Action().(EthCompatibleAction)
if !ok {
// action type not supported
Expand Down
9 changes: 9 additions & 0 deletions action/params.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package action

import "github.com/ethereum/go-ethereum/params"

const (
MaxBlobGasPerBlock = 6 * params.BlobTxBlobGasPerBlob
BlobTxTargetBlobGasPerBlock = 3 * params.BlobTxBlobGasPerBlob
BlobTxBlobGaspriceUpdateFraction = 3338477
)
11 changes: 4 additions & 7 deletions action/protocol/account/util/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,16 +67,13 @@ func StoreAccount(sm protocol.StateManager, addr address.Address, account *state
}

// Recorded tests if an account has been actually stored
func Recorded(sr protocol.StateReader, addr address.Address) (bool, error) {
func Recorded(sr protocol.StateReader, addr address.Address) (*state.Account, error) {
account := &state.Account{}
_, err := sr.State(account, protocol.LegacyKeyOption(hash.BytesToHash160(addr.Bytes())))
switch errors.Cause(err) {
case nil:
return true, nil
case state.ErrStateNotExist:
return false, nil
if err != nil {
return nil, err
}
return false, err
return account, nil
}

// AccountState returns the confirmed account state on the chain
Expand Down
2 changes: 2 additions & 0 deletions action/protocol/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@ type (
CandidateSlashByOwner bool
CandidateBLSPublicKeyNotCopied bool
OnlyOwnerCanUpdateBLSPublicKey bool
PrePectraEVM bool
}

// FeatureWithHeightCtx provides feature check functions.
Expand Down Expand Up @@ -335,6 +336,7 @@ func WithFeatureCtx(ctx context.Context) context.Context {
CandidateSlashByOwner: !g.IsXinguBeta(height),
CandidateBLSPublicKeyNotCopied: !g.IsXinguBeta(height),
OnlyOwnerCanUpdateBLSPublicKey: !g.IsToBeEnabled(height),
PrePectraEVM: !g.IsToBeEnabled(height),
},
)
}
Expand Down
13 changes: 9 additions & 4 deletions action/protocol/eip1559.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import (
"math/big"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/math"
"github.com/pkg/errors"

"github.com/iotexproject/iotex-core/v2/action"
Expand Down Expand Up @@ -56,8 +55,10 @@ func CalcBaseFee(g genesis.Blockchain, parent *TipInfo) *big.Int {
num.Mul(num, parent.BaseFee)
num.Div(num, denom.SetUint64(parentGasTarget))
num.Div(num, denom.SetUint64(action.DefaultBaseFeeChangeDenominator))
baseFeeDelta := math.BigMax(num, common.Big1)
return num.Add(parent.BaseFee, baseFeeDelta)
if num.Cmp(common.Big1) < 0 {
return num.Add(parent.BaseFee, common.Big1)
}
return num.Add(parent.BaseFee, num)
} else {
// Otherwise if the parent block used less gas than its target, the baseFee should decrease.
// max(0, parentBaseFee * gasUsedDelta / parentGasTarget / baseFeeChangeDenominator)
Expand All @@ -66,6 +67,10 @@ func CalcBaseFee(g genesis.Blockchain, parent *TipInfo) *big.Int {
num.Div(num, denom.SetUint64(parentGasTarget))
num.Div(num, denom.SetUint64(action.DefaultBaseFeeChangeDenominator))
baseFee := num.Sub(parent.BaseFee, num)
return math.BigMax(baseFee, new(big.Int).SetUint64(action.InitialBaseFee))
initBaseFee := new(big.Int).SetUint64(action.InitialBaseFee)
if baseFee.Cmp(initBaseFee) < 0 {
baseFee = initBaseFee
}
return baseFee
}
}
12 changes: 7 additions & 5 deletions action/protocol/eip4844.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import (
"math/big"

"github.com/ethereum/go-ethereum/params"

"github.com/iotexproject/iotex-core/v2/action"
)

type (
Expand All @@ -17,16 +19,16 @@ type (

var (
minBlobGasPrice = big.NewInt(params.BlobTxMinBlobGasprice)
blobGaspriceUpdateFraction = big.NewInt(params.BlobTxBlobGaspriceUpdateFraction)
blobGaspriceUpdateFraction = big.NewInt(action.BlobTxBlobGaspriceUpdateFraction)
)

// VerifyEIP4844Header verifies the presence of the excessBlobGas field and that
// if the current block contains no transactions, the excessBlobGas is updated
// accordingly.
func VerifyEIP4844Header(parent *TipInfo, header blockHeader) error {
// Verify that the blob gas used remains within reasonable limits.
if header.BlobGasUsed() > params.MaxBlobGasPerBlock {
return fmt.Errorf("blob gas used %d exceeds maximum allowance %d", header.BlobGasUsed(), params.MaxBlobGasPerBlock)
if header.BlobGasUsed() > action.MaxBlobGasPerBlock {
return fmt.Errorf("blob gas used %d exceeds maximum allowance %d", header.BlobGasUsed(), action.MaxBlobGasPerBlock)
}
if header.BlobGasUsed()%params.BlobTxBlobGasPerBlob != 0 {
return fmt.Errorf("blob gas used %d not a multiple of blob gas per blob %d", header.BlobGasUsed(), params.BlobTxBlobGasPerBlob)
Expand All @@ -48,10 +50,10 @@ func VerifyEIP4844Header(parent *TipInfo, header blockHeader) error {
// blobs on top of the excess blob gas.
func CalcExcessBlobGas(parentExcessBlobGas uint64, parentBlobGasUsed uint64) uint64 {
excessBlobGas := parentExcessBlobGas + parentBlobGasUsed
if excessBlobGas < params.BlobTxTargetBlobGasPerBlock {
if excessBlobGas < action.BlobTxTargetBlobGasPerBlock {
return 0
}
return excessBlobGas - params.BlobTxTargetBlobGasPerBlock
return excessBlobGas - action.BlobTxTargetBlobGasPerBlock
}

// CalcBlobFee calculates the blobfee from the header's excess blob gas field.
Expand Down
21 changes: 10 additions & 11 deletions action/protocol/eip4844_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import (

"github.com/ethereum/go-ethereum/params"
"github.com/stretchr/testify/require"

"github.com/iotexproject/iotex-core/v2/action"
)

func TestCalcExcessBlobGas(t *testing.T) {
Expand All @@ -20,20 +22,20 @@ func TestCalcExcessBlobGas(t *testing.T) {
// slots are below - or equal - to the target.
{0, 0, 0},
{0, 1, 0},
{0, params.BlobTxTargetBlobGasPerBlock / params.BlobTxBlobGasPerBlob, 0},
{0, action.BlobTxTargetBlobGasPerBlock / params.BlobTxBlobGasPerBlob, 0},

// If the target blob gas is exceeded, the excessBlobGas should increase
// by however much it was overshot
{0, (params.BlobTxTargetBlobGasPerBlock / params.BlobTxBlobGasPerBlob) + 1, params.BlobTxBlobGasPerBlob},
{1, (params.BlobTxTargetBlobGasPerBlock / params.BlobTxBlobGasPerBlob) + 1, params.BlobTxBlobGasPerBlob + 1},
{1, (params.BlobTxTargetBlobGasPerBlock / params.BlobTxBlobGasPerBlob) + 2, 2*params.BlobTxBlobGasPerBlob + 1},
{0, (action.BlobTxTargetBlobGasPerBlock / params.BlobTxBlobGasPerBlob) + 1, params.BlobTxBlobGasPerBlob},
{1, (action.BlobTxTargetBlobGasPerBlock / params.BlobTxBlobGasPerBlob) + 1, params.BlobTxBlobGasPerBlob + 1},
{1, (action.BlobTxTargetBlobGasPerBlock / params.BlobTxBlobGasPerBlob) + 2, 2*params.BlobTxBlobGasPerBlob + 1},

// The excess blob gas should decrease by however much the target was
// under-shot, capped at zero.
{params.BlobTxTargetBlobGasPerBlock, params.BlobTxTargetBlobGasPerBlock / params.BlobTxBlobGasPerBlob, params.BlobTxTargetBlobGasPerBlock},
{params.BlobTxTargetBlobGasPerBlock, (params.BlobTxTargetBlobGasPerBlock / params.BlobTxBlobGasPerBlob) - 1, params.BlobTxTargetBlobGasPerBlock - params.BlobTxBlobGasPerBlob},
{params.BlobTxTargetBlobGasPerBlock, (params.BlobTxTargetBlobGasPerBlock / params.BlobTxBlobGasPerBlob) - 2, params.BlobTxTargetBlobGasPerBlock - (2 * params.BlobTxBlobGasPerBlob)},
{params.BlobTxBlobGasPerBlob - 1, (params.BlobTxTargetBlobGasPerBlock / params.BlobTxBlobGasPerBlob) - 1, 0},
{action.BlobTxTargetBlobGasPerBlock, action.BlobTxTargetBlobGasPerBlock / params.BlobTxBlobGasPerBlob, action.BlobTxTargetBlobGasPerBlock},
{action.BlobTxTargetBlobGasPerBlock, (action.BlobTxTargetBlobGasPerBlock / params.BlobTxBlobGasPerBlob) - 1, action.BlobTxTargetBlobGasPerBlock - params.BlobTxBlobGasPerBlob},
{action.BlobTxTargetBlobGasPerBlock, (action.BlobTxTargetBlobGasPerBlock / params.BlobTxBlobGasPerBlob) - 2, action.BlobTxTargetBlobGasPerBlock - (2 * params.BlobTxBlobGasPerBlob)},
{params.BlobTxBlobGasPerBlob - 1, (action.BlobTxTargetBlobGasPerBlock / params.BlobTxBlobGasPerBlob) - 1, 0},
}
for i, tt := range tests {
result := CalcExcessBlobGas(tt.excess, tt.blobs*params.BlobTxBlobGasPerBlob)
Expand Down Expand Up @@ -96,10 +98,7 @@ func TestFakeExponential(t *testing.T) {
func TestEIP4844Params(t *testing.T) {
require := require.New(t)
require.Equal(1<<17, params.BlobTxBlobGasPerBlob)
require.Equal(3*params.BlobTxBlobGasPerBlob, params.BlobTxTargetBlobGasPerBlock)
require.Equal(6*params.BlobTxBlobGasPerBlob, params.MaxBlobGasPerBlock)
require.Equal(1, params.BlobTxMinBlobGasprice)
require.Equal(3338477, params.BlobTxBlobGaspriceUpdateFraction)
require.Equal(4096, params.BlobTxFieldElementsPerBlob)
require.Equal(32, params.BlobTxBytesPerFieldElement)
}
59 changes: 33 additions & 26 deletions action/protocol/execution/evm/evm.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (

erigonstate "github.com/erigontech/erigon/core/state"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/tracing"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/crypto"
Expand Down Expand Up @@ -65,8 +66,8 @@ func CanTransfer(db vm.StateDB, fromHash common.Address, balance *uint256.Int) b

// MakeTransfer transfers account
func MakeTransfer(db vm.StateDB, fromHash, toHash common.Address, amount *uint256.Int) {
db.SubBalance(fromHash, amount)
db.AddBalance(toHash, amount)
db.SubBalance(fromHash, amount, tracing.BalanceChangeUnspecified)
db.AddBalance(toHash, amount, tracing.BalanceChangeUnspecified)

db.AddLog(&types.Log{
Topics: []common.Hash{
Expand Down Expand Up @@ -237,7 +238,7 @@ func securityDeposit(ps *Params, stateDB vm.StateDB, gasLimit uint64) error {
if stateDB.GetBalance(ps.txCtx.Origin).Cmp(gasConsumed) < 0 {
return action.ErrInsufficientFunds
}
stateDB.SubBalance(ps.txCtx.Origin, gasConsumed)
stateDB.SubBalance(ps.txCtx.Origin, gasConsumed, tracing.BalanceChangeUnspecified)
return nil
}

Expand Down Expand Up @@ -289,11 +290,11 @@ func ExecuteContract(
)
if ps.featureCtx.FixDoubleChargeGas {
// Refund all deposit and, actual gas fee will be subtracted when depositing gas fee to the rewarding protocol
stateDB.AddBalance(ps.txCtx.Origin, uint256.MustFromBig(big.NewInt(0).Mul(big.NewInt(0).SetUint64(depositGas), ps.txCtx.GasPrice)))
stateDB.AddBalance(ps.txCtx.Origin, uint256.MustFromBig(big.NewInt(0).Mul(big.NewInt(0).SetUint64(depositGas), ps.txCtx.GasPrice)), tracing.BalanceChangeUnspecified)
} else {
if remainingGas > 0 {
remainingValue := new(big.Int).Mul(new(big.Int).SetUint64(remainingGas), ps.txCtx.GasPrice)
stateDB.AddBalance(ps.txCtx.Origin, uint256.MustFromBig(remainingValue))
stateDB.AddBalance(ps.txCtx.Origin, uint256.MustFromBig(remainingValue), tracing.BalanceChangeUnspecified)
}
if consumedGas > 0 {
burnLog = &action.TransactionLog{
Expand Down Expand Up @@ -448,6 +449,9 @@ func prepareStateDB(ctx context.Context, sm protocol.StateManager) (*StateDBAdap
opts = append(opts, FixRevertSnapshotOption())
opts = append(opts, WithContext(ctx))
}
if featureCtx.PrePectraEVM {
opts = append(opts, IgnoreBalanceChangeTouchAccountOption())
}
return NewStateDBAdapter(
sm,
blkCtx.BlockHeight,
Expand Down Expand Up @@ -527,7 +531,8 @@ func executeInEVM(ctx context.Context, evmParams *Params, stateDB stateDB) ([]by
var (
accessList types.AccessList
)
evm := vm.NewEVM(evmParams.context, evmParams.txCtx, stateDB, chainConfig, evmParams.evmConfig)
evm := vm.NewEVM(evmParams.context, stateDB, chainConfig, evmParams.evmConfig)
evm.SetTxContext(evmParams.txCtx)
if g.IsOkhotsk(blockHeight) {
accessList = evmParams.accessList
}
Expand All @@ -547,17 +552,18 @@ func executeInEVM(ctx context.Context, evmParams *Params, stateDB stateDB) ([]by
}
var (
contractRawAddress = action.EmptyAddress
executor = vm.AccountRef(evmParams.txCtx.Origin)
executor = evmParams.txCtx.Origin
ret []byte
evmErr error
refund uint64
amount = uint256.MustFromBig(evmParams.amount)
)
if evm.Config.Tracer != nil {
evm.Config.Tracer.CaptureTxStart(remainingGas)
defer func() {
evm.Config.Tracer.CaptureTxEnd(remainingGas)
}()
// TODO(pectra): add proper tracing support
// evm.Config.Tracer.OnTxStart(remainingGas)
// defer func() {
// evm.Config.Tracer.CaptureTxEnd(remainingGas)
// }()
}
if evmParams.contract == nil {
// create contract
Expand All @@ -576,7 +582,7 @@ func executeInEVM(ctx context.Context, evmParams *Params, stateDB stateDB) ([]by
ret = createRet
}
} else {
stateDB.SetNonce(evmParams.txCtx.Origin, stateDB.GetNonce(evmParams.txCtx.Origin)+1)
stateDB.SetNonce(evmParams.txCtx.Origin, stateDB.GetNonce(evmParams.txCtx.Origin)+1, tracing.NonceChangeUnspecified)
// process contract
ret, remainingGas, evmErr = evm.Call(executor, *evmParams.contract, evmParams.data, remainingGas, amount)
}
Expand Down Expand Up @@ -641,41 +647,42 @@ func executeInEVM(ctx context.Context, evmParams *Params, stateDB stateDB) ([]by
func evmErrToErrStatusCode(evmErr error, g genesis.Blockchain, height uint64) iotextypes.ReceiptStatus {
// specific error starting London
if g.IsOkhotsk(height) {
if evmErr == vm.ErrInvalidCode {
if errors.Is(evmErr, vm.ErrInvalidCode) {
return iotextypes.ReceiptStatus_ErrInvalidCode
}
}

// specific error starting Jutland
if g.IsJutland(height) {
switch evmErr {
case vm.ErrInsufficientBalance:
switch {
case errors.Is(evmErr, vm.ErrInsufficientBalance):
return iotextypes.ReceiptStatus_ErrInsufficientBalance
case vm.ErrInvalidJump:
case errors.Is(evmErr, vm.ErrInvalidJump):
return iotextypes.ReceiptStatus_ErrInvalidJump
case vm.ErrReturnDataOutOfBounds:
case errors.Is(evmErr, vm.ErrReturnDataOutOfBounds):
return iotextypes.ReceiptStatus_ErrReturnDataOutOfBounds
case vm.ErrGasUintOverflow:
case errors.Is(evmErr, vm.ErrGasUintOverflow):
return iotextypes.ReceiptStatus_ErrGasUintOverflow
}
}

// specific error starting Bering
if g.IsBering(height) {
switch evmErr {
case vm.ErrOutOfGas:
switch {
// the evm error may be wrapped by fmt.Errorf("%w: ..."), so we use errors.Is to check
case errors.Is(evmErr, vm.ErrOutOfGas):
return iotextypes.ReceiptStatus_ErrOutOfGas
case vm.ErrCodeStoreOutOfGas:
case errors.Is(evmErr, vm.ErrCodeStoreOutOfGas):
return iotextypes.ReceiptStatus_ErrCodeStoreOutOfGas
case vm.ErrDepth:
case errors.Is(evmErr, vm.ErrDepth):
return iotextypes.ReceiptStatus_ErrDepth
case vm.ErrContractAddressCollision:
case errors.Is(evmErr, vm.ErrContractAddressCollision):
return iotextypes.ReceiptStatus_ErrContractAddressCollision
case vm.ErrExecutionReverted:
case errors.Is(evmErr, vm.ErrExecutionReverted):
return iotextypes.ReceiptStatus_ErrExecutionReverted
case vm.ErrMaxCodeSizeExceeded:
case errors.Is(evmErr, vm.ErrMaxCodeSizeExceeded):
return iotextypes.ReceiptStatus_ErrMaxCodeSizeExceeded
case vm.ErrWriteProtection:
case errors.Is(evmErr, vm.ErrWriteProtection):
return iotextypes.ReceiptStatus_ErrWriteProtection
default:
// internal errors from go-ethereum are not directly accessible
Expand Down
3 changes: 2 additions & 1 deletion action/protocol/execution/evm/evm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,8 @@ func TestConstantinople(t *testing.T) {
ps, err := newParams(fCtx, elp)
require.NoError(err)

evm := vm.NewEVM(ps.context, ps.txCtx, stateDB, ps.chainConfig, ps.evmConfig)
evm := vm.NewEVM(ps.context, stateDB, ps.chainConfig, ps.evmConfig)
evm.SetTxContext(ps.txCtx)
evmChainConfig := evm.ChainConfig()
require.Equal(g.IsGreenland(e.height), evmChainConfig.IsHomestead(evm.Context.BlockNumber))
require.False(evmChainConfig.IsDAOFork(evm.Context.BlockNumber))
Expand Down
Loading