-
Notifications
You must be signed in to change notification settings - Fork 251
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Adding transaction_call endpoint #832
base: master
Are you sure you want to change the base?
Changes from all commits
515c03d
8ff45c0
401d1b2
e3d3a08
9c85e65
c790152
f435ab8
da734f1
0aa4d38
099f6b9
9ae2e4b
eb47f49
be4777c
1ab62ba
7ceaf29
5c167fb
cb0e53d
65005a2
1971e10
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,6 +7,7 @@ | |
|
||
import ( | ||
"bufio" | ||
"encoding/json" | ||
"errors" | ||
"net" | ||
"net/http" | ||
|
@@ -25,6 +26,7 @@ | |
} | ||
metricHTTPReqCounter = metrics.LazyLoadCounterVec("api_request_count", []string{"name", "code", "method"}) | ||
metricHTTPReqDuration = metrics.LazyLoadHistogramVec("api_duration_ms", []string{"name", "code", "method"}, metrics.BucketHTTPReqs) | ||
metricTxCallVMErrors = metrics.LazyLoadCounterVec("api_tx_call_vm_errors", []string{"error"}) | ||
metricWebsocketDuration = metrics.LazyLoadHistogramVec("api_websocket_duration", []string{"name", "code"}, websocketDurations) | ||
metricActiveWebsocketGauge = metrics.LazyLoadGaugeVec("api_active_websocket_gauge", []string{"name"}) | ||
metricWebsocketCounter = metrics.LazyLoadCounterVec("api_websocket_counter", []string{"name"}) | ||
|
@@ -40,11 +42,35 @@ | |
return &metricsResponseWriter{w, http.StatusOK} | ||
} | ||
|
||
type callTxResponseWriter struct { | ||
http.ResponseWriter | ||
statusCode int | ||
VMError string | ||
} | ||
|
||
func newCallTxResponseWriter(w http.ResponseWriter) *callTxResponseWriter { | ||
return &callTxResponseWriter{w, http.StatusOK, ""} | ||
} | ||
|
||
func (m *metricsResponseWriter) WriteHeader(code int) { | ||
m.statusCode = code | ||
m.ResponseWriter.WriteHeader(code) | ||
} | ||
|
||
func (c *callTxResponseWriter) Write(b []byte) (int, error) { | ||
var resp struct { | ||
VMError string `json:"VMError"` | ||
} | ||
|
||
if err := json.Unmarshal(b, &resp); err == nil { | ||
if resp.VMError != "" { | ||
c.VMError = resp.VMError | ||
} | ||
} | ||
|
||
return c.ResponseWriter.Write(b) | ||
Check warning Code scanning / CodeQL Reflected cross-site scripting Medium
Cross-site scripting vulnerability due to
user-provided value Error loading related location Loading Cross-site scripting vulnerability due to user-provided value Error loading related location Loading |
||
} | ||
|
||
// Hijack complies the writer with WS subscriptions interface | ||
// Hijack lets the caller take over the connection. | ||
// After a call to Hijack the HTTP server library | ||
|
@@ -71,10 +97,23 @@ | |
subscription = false | ||
) | ||
|
||
// all named route will be recorded | ||
if rt != nil && rt.GetName() != "" { | ||
enabled = true | ||
name = rt.GetName() | ||
if name == "transactions_call_tx" { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What is the goal of this particular case ? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I guess to separate errors that happened specifically on that endpoint, the name for it is set here. Not sure if that metric is needed, since it's the errors that happened on transactions, that are not mined |
||
ctxWriter := newCallTxResponseWriter(w) | ||
next.ServeHTTP(ctxWriter, r) | ||
|
||
// Record VM error if present | ||
if ctxWriter.VMError != "" { | ||
metricTxCallVMErrors().AddWithLabel(1, map[string]string{ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What happens if there are a high number of different errors here ? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. From the code I read, there is always at most only 1 possible vmerror per transaction, that doesn't depend on the amount of clauses in a transaction. Was that the question? |
||
"error": ctxWriter.VMError, | ||
}) | ||
} | ||
return | ||
} | ||
|
||
// Handle subscriptions | ||
if strings.HasPrefix(name, "WS") { | ||
subscription = true | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I haven't tried but when this yml gets generated, does it contain a working example ? (like the other endpoints)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think so, but do you mean examples for values? like here
or code/usage example?