Skip to content
This repository was archived by the owner on Apr 11, 2021. It is now read-only.
Closed
Show file tree
Hide file tree
Changes from all commits
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
12 changes: 4 additions & 8 deletions core/vm/evm.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,15 +49,11 @@ func run(evm *EVM, contract *Contract, input []byte, readOnly bool) ([]byte, err
// Intercept the StateManager calls
if contract.Address() == StateManagerAddress {
log.Debug("Calling State Manager contract.", "StateManagerAddress", hex.EncodeToString(StateManagerAddress.Bytes()))
gas := stateManagerRequiredGas(input)
if contract.UseGas(gas) {
ret, err := callStateManager(input, evm, contract)
if err != nil {
log.Error("State manager error!", "Error", err)
}
return ret, err
ret, err := callStateManager(input, evm, contract)
if err != nil {
log.Error("State manager error!", err)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing the Error key here before the err. It looks like in this case it'll append nil and the formatting will look weird.

See:

if len(ctx)%2 != 0 {

}
return nil, ErrOutOfGas
return ret, err
}

if contract.CodeAddr != nil {
Expand Down
72 changes: 16 additions & 56 deletions core/vm/state_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,55 +11,23 @@ import (
"github.com/ethereum/go-ethereum/log"
)

type stateManagerFunctionAndGasCost struct {
smFunction stateManagerFunction
smGasCost uint64
}
type stateManagerFunction func(*EVM, *Contract, []byte) ([]byte, error)

var funcs = map[string]stateManagerFunctionAndGasCost{
"getStorage(address,bytes32)": {
smFunction: getStorage,
smGasCost: 20000,
},
"setStorage(address,bytes32,bytes32)": {
smFunction: setStorage,
smGasCost: 20000,
},
"getOvmContractNonce(address)": {
smFunction: getOvmContractNonce,
smGasCost: 20000,
},
"incrementOvmContractNonce(address)": {
smFunction: incrementOvmContractNonce,
smGasCost: 20000,
},
"getCodeContractBytecode(address)": {
smFunction: getCodeContractBytecode,
smGasCost: 20000,
},
"getCodeContractHash(address)": {
smFunction: getCodeContractHash,
smGasCost: 20000,
},
"getCodeContractAddressFromOvmAddress(address)": {
smFunction: getCodeContractAddress,
smGasCost: 20000,
},
"associateCodeContract(address,address)": {
smFunction: associateCodeContract,
smGasCost: 20000,
},
"registerCreatedContract(address)": {
smFunction: registerCreatedContract,
smGasCost: 20000,
},
var funcs = map[string]stateManagerFunction{
"getStorage(address,bytes32)": getStorage,
"setStorage(address,bytes32,bytes32)": setStorage,
"getOvmContractNonce(address)": getOvmContractNonce,
"incrementOvmContractNonce(address)": incrementOvmContractNonce,
"getCodeContractBytecode(address)": getCodeContractBytecode,
"getCodeContractHash(address)": getCodeContractHash,
"getCodeContractAddressFromOvmAddress(address)": getCodeContractAddress,
"associateCodeContract(address,address)": associateCodeContract,
"registerCreatedContract(address)": registerCreatedContract,
}

var methodIds map[[4]byte]stateManagerFunctionAndGasCost
var methodIds map[[4]byte]stateManagerFunction

func init() {
methodIds = make(map[[4]byte]stateManagerFunctionAndGasCost, len(funcs))
methodIds = make(map[[4]byte]stateManagerFunction, len(funcs))
for methodSignature, f := range funcs {
methodIds[methodSignatureToMethodID(methodSignature)] = f
}
Expand All @@ -71,24 +39,16 @@ func methodSignatureToMethodID(methodSignature string) [4]byte {
return methodID
}

func stateManagerRequiredGas(input []byte) (gas uint64) {
var methodID [4]byte
copy(methodID[:], input[:4])
gas = methodIds[methodID].smGasCost
return gas
}

func callStateManager(input []byte, evm *EVM, contract *Contract) (ret []byte, err error) {
var methodID [4]byte
if len(input) == 0 {
return nil, nil
}
copy(methodID[:], input[:4])
ret, err = methodIds[methodID].smFunction(evm, contract, input)
ret, err = methodIds[methodID](evm, contract, input)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since methodID is dynamic, this feels a bit safer:

if method, ok := methodIds[methodID]; ok {
    ret, err = method(evm, contract, input)
    return ret, err
}

return nil, errors.New("Method not found")

I don't love the way that the error case of "method not found" isn't returned immediately. To fix this we would check !ok in the if clause but then method isn't in context outside of the if block.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could define method above the check so that it is in scope afterwards. What do you think?

return ret, err
}

/*
* StateManager functions
*/

func setStorage(evm *EVM, contract *Contract, input []byte) (ret []byte, err error) {
address := common.BytesToAddress(input[4:36])
key := common.BytesToHash(input[36:68])
Expand Down
8 changes: 7 additions & 1 deletion rpc/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,13 @@ func (h *handler) handleSubscribe(cp *callProc, msg *jsonrpcMessage) *jsonrpcMes

// runMethod runs the Go callback for an RPC method.
func (h *handler) runMethod(ctx context.Context, msg *jsonrpcMessage, callb *callback, args []reflect.Value) *jsonrpcMessage {
result, err := callb.call(ctx, msg.Method, args)
var result interface{}
var err error
if msg.Method == "eth_estimateGas" {
result = 0xffffffff //Gas Limit

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this may make sense to have in a global variable someplace

} else {
result, err = callb.call(ctx, msg.Method, args)
}
if err != nil {
return msg.errorResponse(err)
}
Expand Down