Compare commits
4 Commits
loginpage-
...
frontend-f
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4b228d9b57 | ||
|
|
08bc3e1ea2 | ||
|
|
a091d39c08 | ||
|
|
35699a41bd |
@@ -19,11 +19,13 @@ const (
|
||||
rpcTimeoutMS = 30000
|
||||
rpcMaxRetries = 3
|
||||
rpcRetryBaseMS = 2000
|
||||
rpcMinIntervalMS = 1000
|
||||
)
|
||||
|
||||
type JsonRpcEthereum struct {
|
||||
rpcURL string
|
||||
client *http.Client
|
||||
lastCallAt time.Time
|
||||
}
|
||||
|
||||
func NewJsonRpcEthereum(rpcURL string) (*JsonRpcEthereum, error) {
|
||||
@@ -58,6 +60,8 @@ type rpcError struct {
|
||||
}
|
||||
|
||||
func (j *JsonRpcEthereum) callRPC(ctx context.Context, method string, params ...interface{}) (json.RawMessage, error) {
|
||||
j.throttle(ctx)
|
||||
|
||||
if params == nil {
|
||||
params = []interface{}{}
|
||||
}
|
||||
@@ -72,7 +76,25 @@ func (j *JsonRpcEthereum) callRPC(ctx context.Context, method string, params ...
|
||||
return nil, fmt.Errorf("marshal RPC request: %w", err)
|
||||
}
|
||||
|
||||
return j.callWithRetry(ctx, method, body)
|
||||
result, callErr := j.callWithRetry(ctx, method, body)
|
||||
j.lastCallAt = time.Now()
|
||||
|
||||
return result, callErr
|
||||
}
|
||||
|
||||
func (j *JsonRpcEthereum) throttle(ctx context.Context) {
|
||||
if j.lastCallAt.IsZero() {
|
||||
return
|
||||
}
|
||||
minInterval := time.Duration(rpcMinIntervalMS) * time.Millisecond
|
||||
elapsed := time.Since(j.lastCallAt)
|
||||
if elapsed >= minInterval {
|
||||
return
|
||||
}
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
case <-time.After(minInterval - elapsed):
|
||||
}
|
||||
}
|
||||
|
||||
// callWithRetry executes a JSON-RPC POST with exponential backoff on transient errors.
|
||||
|
||||
BIN
backend/poller
Executable file
BIN
backend/poller
Executable file
Binary file not shown.
@@ -79,6 +79,18 @@
|
||||
animation-delay: 3s;
|
||||
}
|
||||
|
||||
.login-tagline {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
max-width: 630px;
|
||||
margin: 5rem auto 0;
|
||||
padding-left: 2rem;
|
||||
font-style: italic;
|
||||
color: #FFFFFF;
|
||||
font-size: 1.5rem;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.login-interactive-fadein {
|
||||
opacity: 0;
|
||||
animation: fadeIn 2s ease-in-out forwards;
|
||||
|
||||
@@ -87,6 +87,11 @@ export default function Login() {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p className="login-tagline login-card-fadein">
|
||||
A lightweight, on-chain monitoring system giving users real-time
|
||||
situational awareness over blockchain addresses.
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user