2019-11-13 13:55:20 +00:00
|
|
|
package core
|
|
|
|
|
|
|
|
import (
|
|
|
|
"github.com/CityOfZion/neo-go/pkg/core/storage"
|
|
|
|
"github.com/CityOfZion/neo-go/pkg/io"
|
|
|
|
"github.com/CityOfZion/neo-go/pkg/util"
|
|
|
|
"github.com/CityOfZion/neo-go/pkg/vm"
|
|
|
|
"github.com/pkg/errors"
|
|
|
|
)
|
|
|
|
|
|
|
|
// NotificationEvent is a tuple of scripthash that emitted the StackItem as a
|
|
|
|
// notification and that item itself.
|
|
|
|
type NotificationEvent struct {
|
|
|
|
ScriptHash util.Uint160
|
|
|
|
Item vm.StackItem
|
|
|
|
}
|
|
|
|
|
|
|
|
// AppExecResult represent the result of the script execution, gathering together
|
|
|
|
// all resulting notifications, state, stack and other metadata.
|
|
|
|
type AppExecResult struct {
|
|
|
|
TxHash util.Uint256
|
|
|
|
Trigger byte
|
|
|
|
VMState string
|
|
|
|
GasConsumed util.Fixed8
|
|
|
|
Stack string // JSON
|
|
|
|
Events []NotificationEvent
|
|
|
|
}
|
|
|
|
|
|
|
|
// putAppExecResultIntoStore puts given application execution result into the
|
|
|
|
// given store.
|
|
|
|
func putAppExecResultIntoStore(s storage.Store, aer *AppExecResult) error {
|
|
|
|
buf := io.NewBufBinWriter()
|
|
|
|
aer.EncodeBinary(buf.BinWriter)
|
|
|
|
if buf.Err != nil {
|
|
|
|
return buf.Err
|
|
|
|
}
|
2019-11-27 09:23:18 +00:00
|
|
|
key := storage.AppendPrefix(storage.STNotification, aer.TxHash.BytesBE())
|
2019-11-13 13:55:20 +00:00
|
|
|
return s.Put(key, buf.Bytes())
|
|
|
|
}
|
|
|
|
|
|
|
|
// getAppExecResultFromStore gets application execution result from the
|
|
|
|
// given store.
|
|
|
|
func getAppExecResultFromStore(s storage.Store, hash util.Uint256) (*AppExecResult, error) {
|
|
|
|
aer := &AppExecResult{}
|
2019-11-27 09:23:18 +00:00
|
|
|
key := storage.AppendPrefix(storage.STNotification, hash.BytesBE())
|
2019-11-13 13:55:20 +00:00
|
|
|
if b, err := s.Get(key); err == nil {
|
|
|
|
r := io.NewBinReaderFromBuf(b)
|
|
|
|
aer.DecodeBinary(r)
|
|
|
|
if r.Err != nil {
|
|
|
|
return nil, errors.Wrap(r.Err, "decoding failure:")
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
return aer, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// EncodeBinary implements the Serializable interface.
|
2019-12-09 15:25:15 +00:00
|
|
|
func (ne *NotificationEvent) EncodeBinary(w *io.BinWriter) {
|
2019-12-06 15:22:21 +00:00
|
|
|
w.WriteBytes(ne.ScriptHash[:])
|
2019-11-13 13:55:20 +00:00
|
|
|
vm.EncodeBinaryStackItem(ne.Item, w)
|
|
|
|
}
|
|
|
|
|
|
|
|
// DecodeBinary implements the Serializable interface.
|
|
|
|
func (ne *NotificationEvent) DecodeBinary(r *io.BinReader) {
|
2019-12-06 15:37:46 +00:00
|
|
|
r.ReadBytes(ne.ScriptHash[:])
|
2019-11-13 13:55:20 +00:00
|
|
|
ne.Item = vm.DecodeBinaryStackItem(r)
|
|
|
|
}
|
|
|
|
|
|
|
|
// EncodeBinary implements the Serializable interface.
|
|
|
|
func (aer *AppExecResult) EncodeBinary(w *io.BinWriter) {
|
2019-12-06 15:22:21 +00:00
|
|
|
w.WriteBytes(aer.TxHash[:])
|
2019-11-13 13:55:20 +00:00
|
|
|
w.WriteArray(aer.Events)
|
|
|
|
}
|
|
|
|
|
|
|
|
// DecodeBinary implements the Serializable interface.
|
|
|
|
func (aer *AppExecResult) DecodeBinary(r *io.BinReader) {
|
2019-12-06 15:37:46 +00:00
|
|
|
r.ReadBytes(aer.TxHash[:])
|
2019-11-13 13:55:20 +00:00
|
|
|
r.ReadArray(&aer.Events)
|
|
|
|
}
|