Merge pull request #1167 from nspcc-dev/fix-initsslot-for-contract-calls

vm: fix INITSSLOT, it's context-wide, not VM-wide
This commit is contained in:
Roman Khimov 2020-07-09 15:09:52 +03:00 committed by GitHub
commit d234db9864
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 8 additions and 18 deletions

View file

@ -35,6 +35,7 @@ type Context struct {
// Alt stack pointer. // Alt stack pointer.
astack *Stack astack *Stack
static *Slot
local *Slot local *Slot
arguments *Slot arguments *Slot

View file

@ -176,7 +176,7 @@ func testFile(t *testing.T, filename string) {
require.Equal(t, op, opcode.Opcode(ctx.prog[ctx.nextip])) require.Equal(t, op, opcode.Opcode(ctx.prog[ctx.nextip]))
} }
compareStacks(t, s.EStack, vm.estack) compareStacks(t, s.EStack, vm.estack)
compareSlots(t, s.StaticFields, vm.static) compareSlots(t, s.StaticFields, ctx.static)
} }
} }

View file

@ -71,11 +71,6 @@ type VM struct {
estack *Stack // execution stack. estack *Stack // execution stack.
astack *Stack // alt stack. astack *Stack // alt stack.
static *Slot
// Hash to verify in CHECKSIG/CHECKMULTISIG.
checkhash []byte
refs *refCounter refs *refCounter
gasConsumed int64 gasConsumed int64
@ -495,12 +490,6 @@ func (v *VM) AtBreakpoint() bool {
return v.state.HasFlag(breakState) return v.state.HasFlag(breakState)
} }
// SetCheckedHash sets checked hash for CHECKSIG and CHECKMULTISIG instructions.
func (v *VM) SetCheckedHash(h []byte) {
v.checkhash = make([]byte, len(h))
copy(v.checkhash, h)
}
// GetInteropID converts instruction parameter to an interop ID. // GetInteropID converts instruction parameter to an interop ID.
func GetInteropID(parameter []byte) uint32 { func GetInteropID(parameter []byte) uint32 {
return binary.LittleEndian.Uint32(parameter) return binary.LittleEndian.Uint32(parameter)
@ -585,13 +574,13 @@ func (v *VM) execute(ctx *Context, op opcode.Opcode, parameter []byte) (err erro
v.estack.PushVal(result) v.estack.PushVal(result)
case opcode.INITSSLOT: case opcode.INITSSLOT:
if v.static != nil { if ctx.static != nil {
panic("already initialized") panic("already initialized")
} }
if parameter[0] == 0 { if parameter[0] == 0 {
panic("zero argument") panic("zero argument")
} }
v.static = v.newSlot(int(parameter[0])) ctx.static = v.newSlot(int(parameter[0]))
case opcode.INITSLOT: case opcode.INITSLOT:
if ctx.local != nil || ctx.arguments != nil { if ctx.local != nil || ctx.arguments != nil {
@ -612,20 +601,20 @@ func (v *VM) execute(ctx *Context, op opcode.Opcode, parameter []byte) (err erro
} }
case opcode.LDSFLD0, opcode.LDSFLD1, opcode.LDSFLD2, opcode.LDSFLD3, opcode.LDSFLD4, opcode.LDSFLD5, opcode.LDSFLD6: case opcode.LDSFLD0, opcode.LDSFLD1, opcode.LDSFLD2, opcode.LDSFLD3, opcode.LDSFLD4, opcode.LDSFLD5, opcode.LDSFLD6:
item := v.static.Get(int(op - opcode.LDSFLD0)) item := ctx.static.Get(int(op - opcode.LDSFLD0))
v.estack.PushVal(item) v.estack.PushVal(item)
case opcode.LDSFLD: case opcode.LDSFLD:
item := v.static.Get(int(parameter[0])) item := ctx.static.Get(int(parameter[0]))
v.estack.PushVal(item) v.estack.PushVal(item)
case opcode.STSFLD0, opcode.STSFLD1, opcode.STSFLD2, opcode.STSFLD3, opcode.STSFLD4, opcode.STSFLD5, opcode.STSFLD6: case opcode.STSFLD0, opcode.STSFLD1, opcode.STSFLD2, opcode.STSFLD3, opcode.STSFLD4, opcode.STSFLD5, opcode.STSFLD6:
item := v.estack.Pop().Item() item := v.estack.Pop().Item()
v.static.Set(int(op-opcode.STSFLD0), item) ctx.static.Set(int(op-opcode.STSFLD0), item)
case opcode.STSFLD: case opcode.STSFLD:
item := v.estack.Pop().Item() item := v.estack.Pop().Item()
v.static.Set(int(parameter[0]), item) ctx.static.Set(int(parameter[0]), item)
case opcode.LDLOC0, opcode.LDLOC1, opcode.LDLOC2, opcode.LDLOC3, opcode.LDLOC4, opcode.LDLOC5, opcode.LDLOC6: case opcode.LDLOC0, opcode.LDLOC1, opcode.LDLOC2, opcode.LDLOC3, opcode.LDLOC4, opcode.LDLOC5, opcode.LDLOC6:
item := ctx.local.Get(int(op - opcode.LDLOC0)) item := ctx.local.Get(int(op - opcode.LDLOC0))