Skip to content

Commit

Permalink
make invocation saving configurable, safely handle args
Browse files Browse the repository at this point in the history
  • Loading branch information
ixje committed Oct 31, 2024
1 parent 04c71f5 commit dfd5c9b
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 14 deletions.
2 changes: 2 additions & 0 deletions pkg/config/ledger_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ type Ledger struct {
// SkipBlockVerification allows to disable verification of received
// blocks (including cryptographic checks).
SkipBlockVerification bool `yaml:"SkipBlockVerification"`
// SaveInvocations enables contract smart contract invocation data saving.
SaveInvocations bool `yaml:"SaveInvocations"`
}

// Blockchain is a set of settings for core.Blockchain to use, it includes protocol
Expand Down
2 changes: 2 additions & 0 deletions pkg/core/dao/dao_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,8 @@ func TestStoreAsTransaction(t *testing.T) {
Arguments: stackitem.NewArray([]stackitem.Item{
stackitem.NewBool(false),
}),
ArgumentsCount: 1,
IsValid: true,
}},
},
}
Expand Down
22 changes: 17 additions & 5 deletions pkg/core/interop/contract/call.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,23 @@ func Call(ic *interop.Context) error {
}
hasReturn := md.ReturnType != smartcontract.VoidType

ic.InvocationCalls = append(ic.InvocationCalls, state.ContractInvocation{
Hash: u,
Method: method,
Arguments: stackitem.NewArray(args),
})
if ic.Chain.GetConfig().Ledger.SaveInvocations {
arr := stackitem.NewArray(args)
arrCount := len(args)
valid := true
if _, err = ic.DAO.GetItemCtx().Serialize(arr, false); err != nil {
arr = stackitem.NewArray([]stackitem.Item{})
valid = false
}

ic.InvocationCalls = append(ic.InvocationCalls, state.ContractInvocation{
Hash: u,
Method: method,
Arguments: arr,
ArgumentsCount: uint32(arrCount),
IsValid: valid,
})
}
return callInternal(ic, cs, method, fs, hasReturn, args, true)
}

Expand Down
30 changes: 21 additions & 9 deletions pkg/core/state/notification_event.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,11 @@ type NotificationEvent struct {
}

type ContractInvocation struct {
Hash util.Uint160 `json:"contract_hash"`
Method string `json:"method"`
Arguments *stackitem.Array `json:"arguments"`
Hash util.Uint160 `json:"contract_hash"`
Method string `json:"method"`
Arguments *stackitem.Array `json:"arguments"`
ArgumentsCount uint32 `json:"arguments_count"`
IsValid bool `json:"is_valid"`
}

func (ci *ContractInvocation) DecodeBinary(r *io.BinReader) {
Expand All @@ -39,6 +41,8 @@ func (ci *ContractInvocation) DecodeBinary(r *io.BinReader) {
return
}
ci.Arguments = stackitem.NewArray(arr)
ci.ArgumentsCount = r.ReadU32LE()
ci.IsValid = r.ReadBool()
}

func (ci *ContractInvocation) EncodeBinaryWithContext(w *io.BinWriter, sc *stackitem.SerializationContext) {
Expand All @@ -50,6 +54,8 @@ func (ci *ContractInvocation) EncodeBinaryWithContext(w *io.BinWriter, sc *stack
return
}
w.WriteBytes(b)
w.WriteU32LE(ci.ArgumentsCount)
w.WriteBool(ci.IsValid)
}

// MarshalJSON implements the json.Marshaler interface.
Expand All @@ -59,9 +65,11 @@ func (ci ContractInvocation) MarshalJSON() ([]byte, error) {
item = []byte(fmt.Sprintf(`"error: %v"`, err))
}
return json.Marshal(ContractInvocationAux{
Hash: ci.Hash,
Method: ci.Method,
Arguments: item,
Hash: ci.Hash,
Method: ci.Method,
Arguments: item,
ArgumentsCount: ci.ArgumentsCount,
IsValid: ci.IsValid,
})
}

Expand All @@ -81,6 +89,8 @@ func (ci *ContractInvocation) UnmarshalJSON(data []byte) error {
ci.Arguments = params.(*stackitem.Array)
ci.Method = aux.Method
ci.Hash = aux.Hash
ci.ArgumentsCount = aux.ArgumentsCount
ci.IsValid = aux.IsValid
return nil
}

Expand Down Expand Up @@ -286,9 +296,11 @@ type Execution struct {
}

type ContractInvocationAux struct {
Hash util.Uint160 `json:"contract_hash"`
Method string `json:"method"`
Arguments json.RawMessage `json:"arguments"`
Hash util.Uint160 `json:"contract_hash"`
Method string `json:"method"`
Arguments json.RawMessage `json:"arguments"`
ArgumentsCount uint32 `json:"arguments_count"`
IsValid bool `json:"is_valid"`
}

// executionAux represents an auxiliary struct for Execution JSON marshalling.
Expand Down

0 comments on commit dfd5c9b

Please sign in to comment.