Skip to content
This repository has been archived by the owner on Nov 15, 2021. It is now read-only.

Commit

Permalink
removed DYNAMICCALL from dynamic contract invoke implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
localhuman committed Dec 6, 2017
1 parent 10d2501 commit 2529a9a
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 25 deletions.
47 changes: 44 additions & 3 deletions neo/SmartContract/ApplicationEngine.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
from neo.SmartContract import TriggerType

import pdb

from neo.UInt160 import UInt160

class ApplicationEngine(ExecutionEngine):

Expand Down Expand Up @@ -68,7 +68,7 @@ def CheckInvocationStack(self):

opcode = self.CurrentContext.NextInstruction

if opcode == CALL or opcode == APPCALL or opcode == DYNAMICCALL:
if opcode == CALL or opcode == APPCALL:
if self.InvocationStack.Count >= maxStackSize:
logger.error("INVOCATION STACK TOO BIG, RETURN FALSE")
return False
Expand Down Expand Up @@ -165,6 +165,42 @@ def CheckStackSize(self):

return True

def CheckDynamicInvoke(self):

if self.CurrentContext.InstructionPointer >= len(self.CurrentContext.Script):
return True

opcode = self.CurrentContext.NextInstruction

if opcode == APPCALL:

# read the current position of the stream
start_pos = self.CurrentContext.OpReader.stream.tell()


# normal app calls are stored in the op reader
# we read ahead past the next instruction 1 the next 20 bytes
script_hash = self.CurrentContext.OpReader.ReadBytes(21)[1:]

# then reset the position
self.CurrentContext.OpReader.stream.seek(start_pos)

for b in script_hash:
# if any of the bytes are greater than 0, this is a normal app call
if b > 0:
return True


# if this is a dynamic app call, we will arrive here
# get the current executing script hash
current = UInt160(data=self.CurrentContext.ScriptHash())
current_contract_state = self._Table.GetContractState(current.ToBytes())

# if current contract state cant do dynamic calls, return False
return current_contract_state.HasDynamicInvoke

return True

def Execute(self):

while self._VMState & VMState.HALT == 0 and self._VMState & VMState.FAULT == 0:
Expand Down Expand Up @@ -197,6 +233,11 @@ def Execute(self):
logger.error("INVOCATION SIZE TO BIIG")
return False

if not self.CheckDynamicInvoke():
logger.error("Dynamic invoke without proper contract")
return False


self.StepInto()

return not self._VMState & VMState.FAULT > 0
Expand All @@ -213,7 +254,7 @@ def GetPrice(self):

if opcode == NOP:
return 0
elif opcode == APPCALL or opcode == TAILCALL or opcode == DYNAMICCALL:
elif opcode == APPCALL or opcode == TAILCALL:
return 10
elif opcode == SYSCALL:
return self.GetPriceForSysCall()
Expand Down
30 changes: 9 additions & 21 deletions neo/VM/ExecutionEngine.py
Original file line number Diff line number Diff line change
Expand Up @@ -186,34 +186,22 @@ def ExecuteOp(self, opcode, context):
if istack.Count == 0:
self._VMState |= VMState.HALT

elif opcode == APPCALL or opcode == TAILCALL or opcode == DYNAMICCALL:
elif opcode == APPCALL or opcode == TAILCALL:
if self._Table is None:
self._VMState |= VMState.FAULT
return

script_hash = None
script_hash = context.OpReader.ReadBytes(20)

if opcode == DYNAMICCALL:
is_normal_call =False
for b in script_hash:
if b > 0:
is_normal_call=True

script_hash = self._Service.LoadDynamicContractState(self)
if not is_normal_call:
script_hash = self.EvaluationStack.Pop().GetByteArray()

if not script_hash:
logger.error("Could not load dynamic contract state")
self._VMState |= VMState.FAULT
return

current = UInt160(data=self.CurrentContext.ScriptHash())
current_contract_state = self._Table.GetContractState(current.ToBytes())

if not current_contract_state.HasDynamicInvoke:
logger.error("Contract has no dynamic invoke privileges")
self._VMState |= VMState.FAULT
return

else:
script_hash = UInt160(data=context.OpReader.ReadBytes(20)).ToBytes()

script = self._Table.GetScript(script_hash)
script = self._Table.GetScript(UInt160(data=script_hash).ToBytes())

if script is None:
logger.error("Could not find script from script table: %s " % script_hash)
Expand Down
1 change: 0 additions & 1 deletion neo/VM/OpCode.py
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,6 @@
NEWARRAY = b'\xC5' # 用作引用類型
NEWSTRUCT = b'\xC6' # 用作值類型

DYNAMICCALL = b'\xFA'

import sys
import importlib
Expand Down

0 comments on commit 2529a9a

Please sign in to comment.