mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-19 18:32:23 +00:00
rpc, signer: implement jsonrpc2.0 notifications (responseless)
This commit is contained in:
parent
1ff152f3a4
commit
8540a7f088
3 changed files with 56 additions and 5 deletions
|
|
@ -245,6 +245,28 @@ func (c *Client) Call(result interface{}, method string, args ...interface{}) er
|
||||||
return c.CallContext(ctx, result, method, args...)
|
return c.CallContext(ctx, result, method, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Notify sends a JSON-RPC notification with the given arguments, and does not wait for a response,
|
||||||
|
// effectively ignoring any responses sent
|
||||||
|
//
|
||||||
|
// https://www.jsonrpc.org/specification#request_object:
|
||||||
|
// A Notification is a Request object without an "id" member.
|
||||||
|
// A Request object that is a Notification signifies the Client's lack of interest in the
|
||||||
|
// corresponding Response object, and as such no Response object needs to be returned to the client.
|
||||||
|
// The Server MUST NOT reply to a Notification, including those that are within a batch request.
|
||||||
|
func (c *Client) Notify(method string, args ...interface{}) error {
|
||||||
|
ctx := context.Background()
|
||||||
|
msg, err := c.newNotification(method, args...)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if c.isHTTP {
|
||||||
|
err = c.sendHTTP(ctx, nil, msg)
|
||||||
|
} else {
|
||||||
|
err = c.send(ctx, nil, msg)
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
// CallContext performs a JSON-RPC call with the given arguments. If the context is
|
// CallContext performs a JSON-RPC call with the given arguments. If the context is
|
||||||
// canceled before the call has successfully returned, CallContext returns immediately.
|
// canceled before the call has successfully returned, CallContext returns immediately.
|
||||||
//
|
//
|
||||||
|
|
@ -416,9 +438,23 @@ func (c *Client) newMessage(method string, paramsIn ...interface{}) (*jsonrpcMes
|
||||||
return &jsonrpcMessage{Version: "2.0", ID: c.nextID(), Method: method, Params: params}, nil
|
return &jsonrpcMessage{Version: "2.0", ID: c.nextID(), Method: method, Params: params}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Client) newNotification(method string, paramsIn ...interface{}) (*jsonrpcMessage, error) {
|
||||||
|
params, err := json.Marshal(paramsIn)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &jsonrpcMessage{Version: "2.0", Method: method, Params: params}, nil
|
||||||
|
}
|
||||||
|
|
||||||
// send registers op with the dispatch loop, then sends msg on the connection.
|
// send registers op with the dispatch loop, then sends msg on the connection.
|
||||||
// if sending fails, op is deregistered.
|
// if sending fails, op is deregistered.
|
||||||
func (c *Client) send(ctx context.Context, op *requestOp, msg interface{}) error {
|
func (c *Client) send(ctx context.Context, op *requestOp, msg interface{}) error {
|
||||||
|
if jsonrequest, ok := msg.(jsonrpcMessage); ok {
|
||||||
|
if jsonrequest.isNotification() {
|
||||||
|
// If we send a json-rpc notification, we expect no response
|
||||||
|
return c.write(ctx, msg)
|
||||||
|
}
|
||||||
|
}
|
||||||
select {
|
select {
|
||||||
case c.requestOp <- op:
|
case c.requestOp <- op:
|
||||||
log.Trace("", "msg", log.Lazy{Fn: func() string {
|
log.Trace("", "msg", log.Lazy{Fn: func() string {
|
||||||
|
|
|
||||||
|
|
@ -136,6 +136,12 @@ func (c *Client) sendHTTP(ctx context.Context, op *requestOp, msg interface{}) e
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
if jsonrequest, ok := msg.(jsonrpcMessage); ok {
|
||||||
|
if jsonrequest.isNotification() {
|
||||||
|
// If we send a json-rpc notification, we expect no response
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
var respmsg jsonrpcMessage
|
var respmsg jsonrpcMessage
|
||||||
if err := json.NewDecoder(respBody).Decode(&respmsg); err != nil {
|
if err := json.NewDecoder(respBody).Decode(&respmsg); err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
||||||
|
|
@ -49,6 +49,15 @@ func (ui *StdIOUI) dispatch(serviceMethod string, args interface{}, reply interf
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// notify sends a request over the stdio, and does not listen for a response
|
||||||
|
func (ui *StdIOUI) notify(serviceMethod string, args interface{}) error {
|
||||||
|
err := ui.client.Notify(serviceMethod, args)
|
||||||
|
if err != nil {
|
||||||
|
log.Info("Error", "exc", err.Error())
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
func (ui *StdIOUI) ApproveTx(request *SignTxRequest) (SignTxResponse, error) {
|
func (ui *StdIOUI) ApproveTx(request *SignTxRequest) (SignTxResponse, error) {
|
||||||
var result SignTxResponse
|
var result SignTxResponse
|
||||||
err := ui.dispatch("ApproveTx", request, &result)
|
err := ui.dispatch("ApproveTx", request, &result)
|
||||||
|
|
@ -86,34 +95,34 @@ func (ui *StdIOUI) ApproveNewAccount(request *NewAccountRequest) (NewAccountResp
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ui *StdIOUI) ShowError(message string) {
|
func (ui *StdIOUI) ShowError(message string) {
|
||||||
err := ui.dispatch("ShowError", &Message{message}, nil)
|
err := ui.notify("ShowError", &Message{message})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Info("Error calling 'ShowError'", "exc", err.Error(), "msg", message)
|
log.Info("Error calling 'ShowError'", "exc", err.Error(), "msg", message)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ui *StdIOUI) ShowInfo(message string) {
|
func (ui *StdIOUI) ShowInfo(message string) {
|
||||||
err := ui.dispatch("ShowInfo", Message{message}, nil)
|
err := ui.notify("ShowInfo", Message{message})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Info("Error calling 'ShowInfo'", "exc", err.Error(), "msg", message)
|
log.Info("Error calling 'ShowInfo'", "exc", err.Error(), "msg", message)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
func (ui *StdIOUI) OnApprovedTx(tx ethapi.SignTransactionResult) {
|
func (ui *StdIOUI) OnApprovedTx(tx ethapi.SignTransactionResult) {
|
||||||
err := ui.dispatch("OnApprovedTx", tx, nil)
|
err := ui.notify("OnApprovedTx", tx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Info("Error calling 'OnApprovedTx'", "exc", err.Error(), "tx", tx)
|
log.Info("Error calling 'OnApprovedTx'", "exc", err.Error(), "tx", tx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ui *StdIOUI) OnSignerStartup(info StartupInfo) {
|
func (ui *StdIOUI) OnSignerStartup(info StartupInfo) {
|
||||||
err := ui.dispatch("OnSignerStartup", info, nil)
|
err := ui.notify("OnSignerStartup", info)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Info("Error calling 'OnSignerStartup'", "exc", err.Error(), "info", info)
|
log.Info("Error calling 'OnSignerStartup'", "exc", err.Error(), "info", info)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
func (ui *StdIOUI) OnInputRequired(info UserInputRequest) (UserInputResponse, error) {
|
func (ui *StdIOUI) OnInputRequired(info UserInputRequest) (UserInputResponse, error) {
|
||||||
var result UserInputResponse
|
var result UserInputResponse
|
||||||
err := ui.dispatch("OnInputRequired", info, &result)
|
err := ui.notify("OnInputRequired", info)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Info("Error calling 'OnInputRequired'", "exc", err.Error(), "info", info)
|
log.Info("Error calling 'OnInputRequired'", "exc", err.Error(), "info", info)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue