mirror of
https://github.com/nspcc-dev/neo-go.git
synced 2025-05-05 13:06:20 +00:00
core/vm: implement contract storage and script retrieval
Fixes script invocations via the APPCALL instruction. Adjust contract state field types accordingly.
This commit is contained in:
parent
e83dc94744
commit
ceca9cdb67
6 changed files with 175 additions and 16 deletions
29
pkg/vm/vm.go
29
pkg/vm/vm.go
|
@ -35,8 +35,8 @@ type VM struct {
|
|||
// registered interop hooks.
|
||||
interop map[string]InteropFunc
|
||||
|
||||
// scripts loaded in memory.
|
||||
scripts map[util.Uint160][]byte
|
||||
// callback to get scripts.
|
||||
getScript func(util.Uint160) []byte
|
||||
|
||||
istack *Stack // invocation stack.
|
||||
estack *Stack // execution stack.
|
||||
|
@ -51,12 +51,12 @@ type VM struct {
|
|||
// New returns a new VM object ready to load .avm bytecode scripts.
|
||||
func New(mode Mode) *VM {
|
||||
vm := &VM{
|
||||
interop: make(map[string]InteropFunc),
|
||||
scripts: make(map[util.Uint160][]byte),
|
||||
state: haltState,
|
||||
istack: NewStack("invocation"),
|
||||
estack: NewStack("evaluation"),
|
||||
astack: NewStack("alt"),
|
||||
interop: make(map[string]InteropFunc),
|
||||
getScript: nil,
|
||||
state: haltState,
|
||||
istack: NewStack("invocation"),
|
||||
estack: NewStack("evaluation"),
|
||||
astack: NewStack("alt"),
|
||||
}
|
||||
if mode == ModeMute {
|
||||
vm.mute = true
|
||||
|
@ -248,6 +248,11 @@ func (v *VM) SetCheckedHash(h []byte) {
|
|||
copy(v.checkhash, h)
|
||||
}
|
||||
|
||||
// SetScriptGetter sets the script getter for CALL instructions.
|
||||
func (v *VM) SetScriptGetter(gs func(util.Uint160) []byte) {
|
||||
v.getScript = gs
|
||||
}
|
||||
|
||||
// execute performs an instruction cycle in the VM. Acting on the instruction (opcode).
|
||||
func (v *VM) execute(ctx *Context, op Instruction) {
|
||||
// Instead of polluting the whole VM logic with error handling, we will recover
|
||||
|
@ -850,8 +855,8 @@ func (v *VM) execute(ctx *Context, op Instruction) {
|
|||
}
|
||||
|
||||
case APPCALL, TAILCALL:
|
||||
if len(v.scripts) == 0 {
|
||||
panic("script table is empty")
|
||||
if v.getScript == nil {
|
||||
panic("no getScript callback is set up")
|
||||
}
|
||||
|
||||
hash, err := util.Uint160DecodeBytes(ctx.readBytes(20))
|
||||
|
@ -859,8 +864,8 @@ func (v *VM) execute(ctx *Context, op Instruction) {
|
|||
panic(err)
|
||||
}
|
||||
|
||||
script, ok := v.scripts[hash]
|
||||
if !ok {
|
||||
script := v.getScript(hash)
|
||||
if script == nil {
|
||||
panic("could not find script")
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue