Merge pull request #1282 from nspcc-dev/rpc/invoke_with_hashes

rpc: use hashes for verifying in `invoke*` calls
This commit is contained in:
Roman Khimov 2020-08-07 17:00:36 +03:00 committed by GitHub
commit ebcec6e5dc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 183 additions and 69 deletions

View file

@ -1097,24 +1097,37 @@ func (s *Server) invoke(reqParams request.Params) (interface{}, *response.Error)
if err != nil {
return nil, response.ErrInvalidParams
}
hashesForVerifying, err := reqParams.ValueWithType(2, request.ArrayT).GetArrayUint160FromHex()
if err != nil {
return nil, response.ErrInvalidParams
}
script, err := request.CreateInvocationScript(scriptHash, slice)
if err != nil {
return nil, response.NewInternalServerError("can't create invocation script", err)
}
return s.runScriptInVM(script), nil
return s.runScriptInVM(script, hashesForVerifying), nil
}
// invokescript implements the `invokescript` RPC call.
// invokeFunction implements the `invokefunction` RPC call.
func (s *Server) invokeFunction(reqParams request.Params) (interface{}, *response.Error) {
scriptHash, err := reqParams.ValueWithType(0, request.StringT).GetUint160FromHex()
if err != nil {
return nil, response.ErrInvalidParams
}
script, err := request.CreateFunctionInvocationScript(scriptHash, reqParams[1:])
var hashesForVerifying []util.Uint160
hashesForVerifyingIndex := len(reqParams)
if hashesForVerifyingIndex > 3 {
hashesForVerifying, err = reqParams.ValueWithType(3, request.ArrayT).GetArrayUint160FromHex()
if err != nil {
return nil, response.ErrInvalidParams
}
hashesForVerifyingIndex--
}
script, err := request.CreateFunctionInvocationScript(scriptHash, reqParams[1:hashesForVerifyingIndex])
if err != nil {
return nil, response.NewInternalServerError("can't create invocation script", err)
}
return s.runScriptInVM(script), nil
return s.runScriptInVM(script, hashesForVerifying), nil
}
// invokescript implements the `invokescript` RPC call.
@ -1128,13 +1141,27 @@ func (s *Server) invokescript(reqParams request.Params) (interface{}, *response.
return nil, response.ErrInvalidParams
}
return s.runScriptInVM(script), nil
hashesForVerifying, err := reqParams.ValueWithType(1, request.ArrayT).GetArrayUint160FromHex()
if err != nil {
return nil, response.ErrInvalidParams
}
return s.runScriptInVM(script, hashesForVerifying), nil
}
// runScriptInVM runs given script in a new test VM and returns the invocation
// result.
func (s *Server) runScriptInVM(script []byte) *result.Invoke {
vm := s.chain.GetTestVM()
func (s *Server) runScriptInVM(script []byte, scriptHashesForVerifying []util.Uint160) *result.Invoke {
var tx *transaction.Transaction
if count := len(scriptHashesForVerifying); count != 0 {
tx := new(transaction.Transaction)
tx.Attributes = make([]transaction.Attribute, count)
for i, a := range tx.Attributes {
a.Data = scriptHashesForVerifying[i].BytesBE()
a.Usage = transaction.Script
}
}
vm := s.chain.GetTestVM(tx)
vm.SetGasLimit(s.config.MaxGasInvoke)
vm.LoadScript(script)
_ = vm.Run()