This repository has been archived by the owner on Nov 30, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 161
x/evm: logger #272
Merged
Merged
x/evm: logger #272
Changes from all commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,6 +2,7 @@ package types | |
|
||
import ( | ||
"errors" | ||
"fmt" | ||
"math/big" | ||
|
||
"github.com/ethereum/go-ethereum/common" | ||
|
@@ -16,30 +17,58 @@ import ( | |
|
||
// StateTransition defines data to transitionDB in evm | ||
type StateTransition struct { | ||
Payload []byte | ||
Recipient *common.Address | ||
// TxData fields | ||
AccountNonce uint64 | ||
GasLimit uint64 | ||
Price *big.Int | ||
GasLimit uint64 | ||
Recipient *common.Address | ||
Amount *big.Int | ||
ChainID *big.Int | ||
Csdb *CommitStateDB | ||
THash *common.Hash | ||
Sender common.Address | ||
Simulate bool | ||
Payload []byte | ||
|
||
ChainID *big.Int | ||
Csdb *CommitStateDB | ||
TxHash *common.Hash | ||
Sender common.Address | ||
Simulate bool // i.e CheckTx execution | ||
} | ||
|
||
// GasInfo returns the gas limit, gas consumed and gas refunded from the EVM transition | ||
// execution | ||
type GasInfo struct { | ||
GasLimit uint64 | ||
GasConsumed uint64 | ||
GasRefunded uint64 | ||
} | ||
|
||
// ReturnData represents what's returned from a transition | ||
type ReturnData struct { | ||
Logs []*ethtypes.Log | ||
Bloom *big.Int | ||
Result *sdk.Result | ||
// ExecutionResult represents what's returned from a transition | ||
type ExecutionResult struct { | ||
Logs []*ethtypes.Log | ||
Bloom *big.Int | ||
Result *sdk.Result | ||
GasInfo GasInfo | ||
} | ||
|
||
func (st StateTransition) newEVM(ctx sdk.Context, csdb *CommitStateDB, gasLimit uint64, gasPrice *big.Int) *vm.EVM { | ||
// Create context for evm | ||
context := vm.Context{ | ||
CanTransfer: core.CanTransfer, | ||
Transfer: core.Transfer, | ||
Origin: st.Sender, | ||
Coinbase: common.Address{}, // there's no benefitiary since we're not mining | ||
BlockNumber: big.NewInt(ctx.BlockHeight()), | ||
Time: big.NewInt(ctx.BlockHeader().Time.Unix()), | ||
Difficulty: big.NewInt(0), // unused. Only required in PoW context | ||
GasLimit: gasLimit, | ||
GasPrice: gasPrice, | ||
} | ||
|
||
return vm.NewEVM(context, csdb, GenerateChainConfig(st.ChainID), vm.Config{}) | ||
} | ||
|
||
// TODO: move to keeper | ||
// TransitionCSDB performs an evm state transition from a transaction | ||
// TODO: update godoc, it doesn't explain what it does in depth. | ||
func (st StateTransition) TransitionCSDB(ctx sdk.Context) (*ReturnData, error) { | ||
// TransitionDb will transition the state by applying the current transaction and | ||
// returning the evm execution result. | ||
// NOTE: State transition checks are run during AnteHandler execution. | ||
func (st StateTransition) TransitionDb(ctx sdk.Context) (*ExecutionResult, error) { | ||
contractCreation := st.Recipient == nil | ||
|
||
cost, err := core.IntrinsicGas(st.Payload, contractCreation, true, false) | ||
|
@@ -78,58 +107,54 @@ func (st StateTransition) TransitionCSDB(ctx sdk.Context) (*ReturnData, error) { | |
return nil, errors.New("gas price cannot be nil") | ||
} | ||
|
||
// Create context for evm | ||
context := vm.Context{ | ||
CanTransfer: core.CanTransfer, | ||
Transfer: core.Transfer, | ||
Origin: st.Sender, | ||
Coinbase: common.Address{}, // TODO: explain why this is empty | ||
BlockNumber: big.NewInt(ctx.BlockHeight()), | ||
Time: big.NewInt(ctx.BlockHeader().Time.Unix()), | ||
Difficulty: big.NewInt(0), // unused. Only required in PoW context | ||
GasLimit: gasLimit, | ||
GasPrice: gasPrice.BigInt(), | ||
} | ||
|
||
evm := vm.NewEVM(context, csdb, GenerateChainConfig(st.ChainID), vm.Config{}) | ||
evm := st.newEVM(ctx, csdb, gasLimit, gasPrice.BigInt()) | ||
|
||
var ( | ||
ret []byte | ||
leftOverGas uint64 | ||
addr common.Address | ||
senderRef = vm.AccountRef(st.Sender) | ||
ret []byte | ||
leftOverGas uint64 | ||
addr common.Address | ||
recipientLog string | ||
senderRef = vm.AccountRef(st.Sender) | ||
) | ||
|
||
// Get nonce of account outside of the EVM | ||
currentNonce := st.Csdb.GetNonce(st.Sender) | ||
// Set nonce of sender account before evm state transition for usage in generating Create address | ||
st.Csdb.SetNonce(st.Sender, st.AccountNonce) | ||
|
||
// create contract or execute call | ||
switch contractCreation { | ||
case true: | ||
ret, addr, leftOverGas, err = evm.Create(senderRef, st.Payload, gasLimit, st.Amount) | ||
recipientLog = fmt.Sprintf("contract address %s", addr) | ||
default: | ||
// Increment the nonce for the next transaction (just for evm state transition) | ||
csdb.SetNonce(st.Sender, csdb.GetNonce(st.Sender)+1) | ||
ret, leftOverGas, err = evm.Call(senderRef, *st.Recipient, st.Payload, gasLimit, st.Amount) | ||
recipientLog = fmt.Sprintf("recipient address %s", st.Recipient) | ||
} | ||
|
||
gasConsumed := gasLimit - leftOverGas | ||
|
||
if err != nil { | ||
// Consume gas before returning | ||
ctx.GasMeter().ConsumeGas(gasConsumed, "evm execution consumption") | ||
return nil, err | ||
} | ||
|
||
gasConsumed := gasLimit - leftOverGas | ||
|
||
// Resets nonce to value pre state transition | ||
st.Csdb.SetNonce(st.Sender, currentNonce) | ||
|
||
// Generate bloom filter to be saved in tx receipt data | ||
bloomInt := big.NewInt(0) | ||
var bloomFilter ethtypes.Bloom | ||
var logs []*ethtypes.Log | ||
|
||
if st.THash != nil && !st.Simulate { | ||
logs, err = csdb.GetLogs(*st.THash) | ||
var ( | ||
bloomFilter ethtypes.Bloom | ||
logs []*ethtypes.Log | ||
) | ||
|
||
if st.TxHash != nil && !st.Simulate { | ||
logs, err = csdb.GetLogs(*st.TxHash) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
@@ -138,55 +163,51 @@ func (st StateTransition) TransitionCSDB(ctx sdk.Context) (*ReturnData, error) { | |
bloomFilter = ethtypes.BytesToBloom(bloomInt.Bytes()) | ||
} | ||
|
||
if !st.Simulate { | ||
// Finalise state if not a simulated transaction | ||
// TODO: change to depend on config | ||
if err := st.Csdb.Finalise(true); err != nil { | ||
return nil, err | ||
} | ||
} | ||
|
||
// Encode all necessary data into slice of bytes to return in sdk result | ||
res := &ResultData{ | ||
resultData := &ResultData{ | ||
Address: addr, | ||
Bloom: bloomFilter, | ||
Logs: logs, | ||
Ret: ret, | ||
TxHash: *st.THash, | ||
TxHash: *st.TxHash, | ||
} | ||
|
||
resultData, err := EncodeResultData(res) | ||
resBz, err := EncodeResultData(resultData) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
// handle errors | ||
if err != nil { | ||
if err == vm.ErrOutOfGas || err == vm.ErrCodeStoreOutOfGas { | ||
return nil, sdkerrors.Wrap(err, "evm execution went out of gas") | ||
} | ||
resultLog := fmt.Sprintf( | ||
"executed EVM state transition; sender address %s; %s", st.Sender, recipientLog, | ||
) | ||
|
||
// Consume gas before returning | ||
ctx.GasMeter().ConsumeGas(gasConsumed, "EVM execution consumption") | ||
return nil, err | ||
executionResult := &ExecutionResult{ | ||
Logs: logs, | ||
Bloom: bloomInt, | ||
Result: &sdk.Result{ | ||
Data: resBz, | ||
Log: resultLog, | ||
}, | ||
GasInfo: GasInfo{ | ||
GasConsumed: gasConsumed, | ||
GasLimit: gasLimit, | ||
GasRefunded: leftOverGas, | ||
}, | ||
} | ||
|
||
// TODO: Refund unused gas here, if intended in future | ||
|
||
if !st.Simulate { | ||
// Finalise state if not a simulated transaction | ||
// TODO: change to depend on config | ||
if err := st.Csdb.Finalise(true); err != nil { | ||
return nil, err | ||
} | ||
} | ||
|
||
// Consume gas from evm execution | ||
// Out of gas check does not need to be done here since it is done within the EVM execution | ||
ctx.WithGasMeter(currentGasMeter).GasMeter().ConsumeGas(gasConsumed, "EVM execution consumption") | ||
|
||
err = st.Csdb.SetLogs(*st.THash, logs) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. these are already set on the handler |
||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
returnData := &ReturnData{ | ||
Logs: logs, | ||
Bloom: bloomInt, | ||
Result: &sdk.Result{Data: resultData}, | ||
} | ||
|
||
return returnData, nil | ||
return executionResult, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Renamed to match geth's:
https://github.com/ethereum/go-ethereum/blob/26d271dfbba1367326dec38068f9df828d462c61/core/state_transition.go#L71-L77