Skip to content
This repository has been archived by the owner on May 13, 2022. It is now read-only.

issue-476: return One256 for EXTCODESIZE on native contracts #476

Conversation

VoR0220
Copy link
Contributor

@VoR0220 VoR0220 commented Feb 8, 2017

Fixes problem with not being able to get at the Snative contract.

Signed-off-by: RJ Catalano rj@monax.io

@silasdavis
Copy link
Contributor

silasdavis commented Feb 8, 2017

Could you be a bit clearer with "problem with not being able to get at the Snative contract.", what problem prompted your investigation here?

It does seem like there can be a problem here and your solution will in some sense work. However this is a special case of a broader problem. That is making sure we have some special case handling for snatives. The other obvious place this will be an issue is EXTCODECOPY:

https://github.com/eris-ltd/eris-db/blob/master/manager/eris-mint/evm/vm.go#L583

in fact EXTCODESIZE seems like it probably is designed be used in tandem with EXTCODECOPY to copy contract code around. We would need to handle some special case there too at least.

What is the context of use here? Pretending a native contract exists and has code length 1 may make certain code execute, but it doesn't make it make any sense, seems ad hoc, and does nothing to allow you to treat native contracts as if they have code accessible in contract-space. It seems like the best thing to do here might be to just make in an error. But we need more context about where this was encountered.

Another place where we don't check whether we are dealing with an snative, and perhaps we should is in CREATE: https://github.com/eris-ltd/eris-db/blob/master/manager/eris-mint/evm/vm.go#L763

Copy link
Contributor

@benjaminbollen benjaminbollen left a comment

Choose a reason for hiding this comment

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

This will need a proper understanding of the motivating changes in solc; if for snative contracts we would need to return a non-error; then we need to first understand what should be returned;

@@ -565,13 +565,17 @@ func (vm *VM) call(caller, callee *Account, code, input []byte, value int64, gas
}
acc := vm.appState.GetAccount(addr)
if acc == nil {
return nil, firstErr(err, ErrUnknownAddress)
if _, ok := registeredNativeContracts[addr]; !ok {
Copy link
Contributor

Choose a reason for hiding this comment

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

Thus far we have not returned a code size for native contracts. Is this motivated by a change in solidity, where it newly checks the code length before going to a contract. We have not had a problem before calling our snative contracts. Can you document and elaborate?

if _, ok := registeredNativeContracts[addr]; !ok {
return nil, firstErr(err, ErrUnknownAddress)
}
stack.Push64(int64(1))
Copy link
Contributor

Choose a reason for hiding this comment

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

More idiomatic and a little more efficient to use stack.Push(One256) here

@silasdavis
Copy link
Contributor

Here's a fragment of solc 4.4.0 compiled bytecode that helps illuminate what the solidity compiler is up to:

      EXTCODESIZE 			perm.rm_role(addr, role)
      ISZERO 			perm.rm_role(addr, role)
      PUSH [ErrorTag] 			perm.rm_role(addr, role)
      JUMPI 			perm.rm_role(addr, role)
      PUSH 32			perm.rm_role(addr, role)
      GAS 			perm.rm_role(addr, role)
      SUB 			perm.rm_role(addr, role)
      CALL 			perm.rm_role(addr, role)
      ISZERO 			perm.rm_role(addr, role)
      PUSH [ErrorTag] 			perm.rm_role(addr, role)
      JUMPI 			perm.rm_role(addr, role)
      POP 			perm.rm_role(addr, role)
      POP 			perm.rm_role(addr, role)
      POP 			perm.rm_role(addr, role)
      PUSH 40			perm.rm_role(addr, role)

Here's the relevant line in the solidity compiler that generates this type of code: https://github.com/ethereum/solidity/blob/develop/libsolidity/codegen/ExpressionCompiler.cpp#L1662

The check amounts to an existence check for the contract/contract code before running it. I am not certain why this is, but it seems like in the current pricing model it might be better to check the code exists before calling empty code. Worth checking.

In this compiler case returning any truthy value seems to be the right thing to do, and 1 is probably the most elegant.

There is a worry with how this interacts with EXTCODECOPY. It could easily try and copy non-existing bytes into allocated space. However as a point of reassurance, a quick grep of the solidity compiler code does not seem to show any use of EXTCODECOPY by the the solidity code generator.

If someone is deliberately trying to access snative code from an EXTCODECOPY then we have a problem, but an error is probably the right thing to do there from the time being. We could return stub code, but that seems like it would cause more pain than it might prevent. EXTCODECOPY is a low-level thing, and I think solidity is our main concern...

} else {
code := acc.Code
l := int64(len(code))
stack.Push64(l)
Copy link
Contributor

Choose a reason for hiding this comment

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

again, I think this should be stack.Push(One256) it saves doing the conversion to use the constant, and it is used elsewhere

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is the actual code length for normal contracts that are not natives.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It should stay as it is.

@benjaminbollen
Copy link
Contributor

LGTM

@benjaminbollen benjaminbollen changed the base branch from develop to release-0.16 February 8, 2017 17:38
@benjaminbollen benjaminbollen changed the title fixes snative calls from solc issue-476: return One256 for EXTCODESIZE on native contracts Feb 8, 2017
RJ Catalano and others added 4 commits February 8, 2017 11:40
Signed-off-by: RJ Catalano <rj@monax.io>
Signed-off-by: RJ Catalano <rj@monax.io>
Signed-off-by: RJ Catalano <rj@monax.io>
@VoR0220 VoR0220 force-pushed the fixesSNativeCallsFromSolc branch from 8dcb9d0 to 9e141fa Compare February 8, 2017 17:41
@silasdavis silasdavis merged commit 45fbfdd into hyperledger-archives:release-0.16 Feb 8, 2017
silasdavis added a commit to silasdavis/burrow that referenced this pull request Mar 9, 2019
…CallsFromSolc

issue-476: return One256 for EXTCODESIZE on native contracts
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Development

Successfully merging this pull request may close these issues.

3 participants