diff --git a/precompiles/common/errors.go b/precompiles/common/errors.go index f7a93d8e..6570a8d7 100644 --- a/precompiles/common/errors.go +++ b/precompiles/common/errors.go @@ -4,4 +4,5 @@ const ( ErrGetStateDB = "get EVM StateDB failed" ErrInvalidNumberOfArgs = "invalid number of arguments; expected %d; got: %d" ErrSenderNotOrigin = "msg.sender is not from tx origin" + ErrWriteOnReadOnly = "read only call to write functions" ) diff --git a/precompiles/dasigners/dasigners.go b/precompiles/dasigners/dasigners.go index c8cd7e15..615b0f95 100644 --- a/precompiles/dasigners/dasigners.go +++ b/precompiles/dasigners/dasigners.go @@ -92,6 +92,17 @@ func (d *DASignersPrecompile) RequiredGas(input []byte) uint64 { return RequiredGasMax } +func (d *DASignersPrecompile) IsTx(method string) bool { + switch method { + case DASignersFunctionUpdateSocket, + DASignersFunctionRegisterSigner, + DASignersFunctionRegisterNextEpoch: + return true + default: + return false + } +} + // Run implements vm.PrecompiledContract. func (d *DASignersPrecompile) Run(evm *vm.EVM, contract *vm.Contract, readonly bool) ([]byte, error) { // parse input @@ -106,6 +117,10 @@ func (d *DASignersPrecompile) Run(evm *vm.EVM, contract *vm.Contract, readonly b if err != nil { return nil, err } + // readonly check + if readonly && d.IsTx(method.Name) { + return nil, fmt.Errorf(precopmiles_common.ErrWriteOnReadOnly) + } // get state db and context stateDB, ok := evm.StateDB.(*statedb.StateDB) if !ok { diff --git a/precompiles/staking/staking.go b/precompiles/staking/staking.go index 67d4a304..e15abf30 100644 --- a/precompiles/staking/staking.go +++ b/precompiles/staking/staking.go @@ -67,6 +67,20 @@ func (s *StakingPrecompile) RequiredGas(input []byte) uint64 { return 0 } +func (s *StakingPrecompile) IsTx(method string) bool { + switch method { + case StakingFunctionCreateValidator, + StakingFunctionEditValidator, + StakingFunctionDelegate, + StakingFunctionBeginRedelegate, + StakingFunctionUndelegate, + StakingFunctionCancelUnbondingDelegation: + return true + default: + return false + } +} + // Run implements vm.PrecompiledContract. func (s *StakingPrecompile) Run(evm *vm.EVM, contract *vm.Contract, readonly bool) ([]byte, error) { // parse input @@ -81,6 +95,10 @@ func (s *StakingPrecompile) Run(evm *vm.EVM, contract *vm.Contract, readonly boo if err != nil { return nil, err } + // readonly check + if readonly && s.IsTx(method.Name) { + return nil, fmt.Errorf(precopmiles_common.ErrWriteOnReadOnly) + } // get state db and context stateDB, ok := evm.StateDB.(*statedb.StateDB) if !ok {