forked from TrueCloudLab/neoneo-go
core: add FaultException to AppExecResult
This commit is contained in:
parent
9a493dd2a0
commit
0f71088246
3 changed files with 69 additions and 33 deletions
|
@ -584,6 +584,7 @@ func (bc *Blockchain) storeBlock(block *block.Block, txpool *mempool.Pool) error
|
||||||
v.GasLimit = tx.SystemFee
|
v.GasLimit = tx.SystemFee
|
||||||
|
|
||||||
err := v.Run()
|
err := v.Run()
|
||||||
|
var faultException string
|
||||||
if !v.HasFailed() {
|
if !v.HasFailed() {
|
||||||
_, err := systemInterop.DAO.Persist()
|
_, err := systemInterop.DAO.Persist()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -597,14 +598,16 @@ func (bc *Blockchain) storeBlock(block *block.Block, txpool *mempool.Pool) error
|
||||||
zap.String("tx", tx.Hash().StringLE()),
|
zap.String("tx", tx.Hash().StringLE()),
|
||||||
zap.Uint32("block", block.Index),
|
zap.Uint32("block", block.Index),
|
||||||
zap.Error(err))
|
zap.Error(err))
|
||||||
|
faultException = err.Error()
|
||||||
}
|
}
|
||||||
aer := &state.AppExecResult{
|
aer := &state.AppExecResult{
|
||||||
TxHash: tx.Hash(),
|
TxHash: tx.Hash(),
|
||||||
Trigger: trigger.Application,
|
Trigger: trigger.Application,
|
||||||
VMState: v.State(),
|
VMState: v.State(),
|
||||||
GasConsumed: v.GasConsumed(),
|
GasConsumed: v.GasConsumed(),
|
||||||
Stack: v.Estack().ToArray(),
|
Stack: v.Estack().ToArray(),
|
||||||
Events: systemInterop.Notifications,
|
Events: systemInterop.Notifications,
|
||||||
|
FaultException: faultException,
|
||||||
}
|
}
|
||||||
appExecResults = append(appExecResults, aer)
|
appExecResults = append(appExecResults, aer)
|
||||||
err = cache.PutAppExecResult(aer, writeBuf)
|
err = cache.PutAppExecResult(aer, writeBuf)
|
||||||
|
|
|
@ -23,12 +23,13 @@ type NotificationEvent struct {
|
||||||
// AppExecResult represent the result of the script execution, gathering together
|
// AppExecResult represent the result of the script execution, gathering together
|
||||||
// all resulting notifications, state, stack and other metadata.
|
// all resulting notifications, state, stack and other metadata.
|
||||||
type AppExecResult struct {
|
type AppExecResult struct {
|
||||||
TxHash util.Uint256
|
TxHash util.Uint256
|
||||||
Trigger trigger.Type
|
Trigger trigger.Type
|
||||||
VMState vm.State
|
VMState vm.State
|
||||||
GasConsumed int64
|
GasConsumed int64
|
||||||
Stack []stackitem.Item
|
Stack []stackitem.Item
|
||||||
Events []NotificationEvent
|
Events []NotificationEvent
|
||||||
|
FaultException string
|
||||||
}
|
}
|
||||||
|
|
||||||
// EncodeBinary implements the Serializable interface.
|
// EncodeBinary implements the Serializable interface.
|
||||||
|
@ -62,6 +63,7 @@ func (aer *AppExecResult) EncodeBinary(w *io.BinWriter) {
|
||||||
w.WriteU64LE(uint64(aer.GasConsumed))
|
w.WriteU64LE(uint64(aer.GasConsumed))
|
||||||
stackitem.EncodeBinaryStackItem(stackitem.NewArray(aer.Stack), w)
|
stackitem.EncodeBinaryStackItem(stackitem.NewArray(aer.Stack), w)
|
||||||
w.WriteArray(aer.Events)
|
w.WriteArray(aer.Events)
|
||||||
|
w.WriteVarBytes([]byte(aer.FaultException))
|
||||||
}
|
}
|
||||||
|
|
||||||
// DecodeBinary implements the Serializable interface.
|
// DecodeBinary implements the Serializable interface.
|
||||||
|
@ -80,6 +82,7 @@ func (aer *AppExecResult) DecodeBinary(r *io.BinReader) {
|
||||||
aer.Stack = arr
|
aer.Stack = arr
|
||||||
}
|
}
|
||||||
r.ReadArray(&aer.Events)
|
r.ReadArray(&aer.Events)
|
||||||
|
aer.FaultException = r.ReadString()
|
||||||
}
|
}
|
||||||
|
|
||||||
// notificationEventAux is an auxiliary struct for NotificationEvent JSON marshalling.
|
// notificationEventAux is an auxiliary struct for NotificationEvent JSON marshalling.
|
||||||
|
@ -123,12 +126,13 @@ func (ne *NotificationEvent) UnmarshalJSON(data []byte) error {
|
||||||
|
|
||||||
// appExecResultAux is an auxiliary struct for JSON marshalling
|
// appExecResultAux is an auxiliary struct for JSON marshalling
|
||||||
type appExecResultAux struct {
|
type appExecResultAux struct {
|
||||||
TxHash *util.Uint256 `json:"txid"`
|
TxHash *util.Uint256 `json:"txid"`
|
||||||
Trigger string `json:"trigger"`
|
Trigger string `json:"trigger"`
|
||||||
VMState string `json:"vmstate"`
|
VMState string `json:"vmstate"`
|
||||||
GasConsumed int64 `json:"gasconsumed,string"`
|
GasConsumed int64 `json:"gasconsumed,string"`
|
||||||
Stack json.RawMessage `json:"stack"`
|
Stack json.RawMessage `json:"stack"`
|
||||||
Events []NotificationEvent `json:"notifications"`
|
Events []NotificationEvent `json:"notifications"`
|
||||||
|
FaultException string `json:"exception,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// MarshalJSON implements implements json.Marshaler interface.
|
// MarshalJSON implements implements json.Marshaler interface.
|
||||||
|
@ -158,12 +162,13 @@ func (aer *AppExecResult) MarshalJSON() ([]byte, error) {
|
||||||
hash = &aer.TxHash
|
hash = &aer.TxHash
|
||||||
}
|
}
|
||||||
return json.Marshal(&appExecResultAux{
|
return json.Marshal(&appExecResultAux{
|
||||||
TxHash: hash,
|
TxHash: hash,
|
||||||
Trigger: aer.Trigger.String(),
|
Trigger: aer.Trigger.String(),
|
||||||
VMState: aer.VMState.String(),
|
VMState: aer.VMState.String(),
|
||||||
GasConsumed: aer.GasConsumed,
|
GasConsumed: aer.GasConsumed,
|
||||||
Stack: st,
|
Stack: st,
|
||||||
Events: aer.Events,
|
Events: aer.Events,
|
||||||
|
FaultException: aer.FaultException,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -202,6 +207,7 @@ func (aer *AppExecResult) UnmarshalJSON(data []byte) error {
|
||||||
aer.VMState = state
|
aer.VMState = state
|
||||||
aer.Events = aux.Events
|
aer.Events = aux.Events
|
||||||
aer.GasConsumed = aux.GasConsumed
|
aer.GasConsumed = aux.GasConsumed
|
||||||
|
aer.FaultException = aux.FaultException
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,16 +24,31 @@ func TestEncodeDecodeNotificationEvent(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestEncodeDecodeAppExecResult(t *testing.T) {
|
func TestEncodeDecodeAppExecResult(t *testing.T) {
|
||||||
appExecResult := &AppExecResult{
|
t.Run("halt", func(t *testing.T) {
|
||||||
TxHash: random.Uint256(),
|
appExecResult := &AppExecResult{
|
||||||
Trigger: 1,
|
TxHash: random.Uint256(),
|
||||||
VMState: vm.HaltState,
|
Trigger: 1,
|
||||||
GasConsumed: 10,
|
VMState: vm.HaltState,
|
||||||
Stack: []stackitem.Item{},
|
GasConsumed: 10,
|
||||||
Events: []NotificationEvent{},
|
Stack: []stackitem.Item{},
|
||||||
}
|
Events: []NotificationEvent{},
|
||||||
|
}
|
||||||
|
|
||||||
testserdes.EncodeDecodeBinary(t, appExecResult, new(AppExecResult))
|
testserdes.EncodeDecodeBinary(t, appExecResult, new(AppExecResult))
|
||||||
|
})
|
||||||
|
t.Run("fault", func(t *testing.T) {
|
||||||
|
appExecResult := &AppExecResult{
|
||||||
|
TxHash: random.Uint256(),
|
||||||
|
Trigger: 1,
|
||||||
|
VMState: vm.FaultState,
|
||||||
|
GasConsumed: 10,
|
||||||
|
Stack: []stackitem.Item{},
|
||||||
|
Events: []NotificationEvent{},
|
||||||
|
FaultException: "unhandled error",
|
||||||
|
}
|
||||||
|
|
||||||
|
testserdes.EncodeDecodeBinary(t, appExecResult, new(AppExecResult))
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMarshalUnmarshalJSONNotificationEvent(t *testing.T) {
|
func TestMarshalUnmarshalJSONNotificationEvent(t *testing.T) {
|
||||||
|
@ -86,6 +101,18 @@ func TestMarshalUnmarshalJSONAppExecResult(t *testing.T) {
|
||||||
testserdes.MarshalUnmarshalJSON(t, appExecResult, new(AppExecResult))
|
testserdes.MarshalUnmarshalJSON(t, appExecResult, new(AppExecResult))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
t.Run("positive, fault state", func(t *testing.T) {
|
||||||
|
appExecResult := &AppExecResult{
|
||||||
|
TxHash: random.Uint256(),
|
||||||
|
Trigger: trigger.Application,
|
||||||
|
VMState: vm.FaultState,
|
||||||
|
GasConsumed: 10,
|
||||||
|
Stack: []stackitem.Item{},
|
||||||
|
Events: []NotificationEvent{},
|
||||||
|
FaultException: "unhandled exception",
|
||||||
|
}
|
||||||
|
testserdes.MarshalUnmarshalJSON(t, appExecResult, new(AppExecResult))
|
||||||
|
})
|
||||||
t.Run("positive, block", func(t *testing.T) {
|
t.Run("positive, block", func(t *testing.T) {
|
||||||
appExecResult := &AppExecResult{
|
appExecResult := &AppExecResult{
|
||||||
TxHash: random.Uint256(),
|
TxHash: random.Uint256(),
|
||||||
|
|
Loading…
Reference in a new issue