good morning!!!!
Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
B
bor
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Iterations
Wiki
Requirements
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Locked files
Build
Pipelines
Jobs
Pipeline schedules
Test cases
Artifacts
Deploy
Releases
Package registry
Container registry
Harbor Registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Code review analytics
Issue analytics
Insights
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
GitLab community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
open
bor
Commits
06d40d37
Unverified
Commit
06d40d37
authored
Sep 21, 2018
by
Péter Szilágyi
Committed by
GitHub
Sep 21, 2018
Browse files
Options
Downloads
Plain Diff
Merge pull request #17732 from karalabe/faucet-caching
cmd/faucet: cache internal state, avoid sync-trashing les
parents
ee92bc53
c528e3e3
Branches
Branches containing commit
Tags
Tags containing commit
No related merge requests found
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
cmd/faucet/faucet.go
+67
-45
67 additions, 45 deletions
cmd/faucet/faucet.go
with
67 additions
and
45 deletions
cmd/faucet/faucet.go
+
67
−
45
View file @
06d40d37
...
...
@@ -199,6 +199,8 @@ type faucet struct {
keystore
*
keystore
.
KeyStore
// Keystore containing the single signer
account
accounts
.
Account
// Account funding user faucet requests
head
*
types
.
Header
// Current head header of the faucet
balance
*
big
.
Int
// Current balance of the faucet
nonce
uint64
// Current pending nonce of the faucet
price
*
big
.
Int
// Current gas price to issue funds with
...
...
@@ -324,33 +326,30 @@ func (f *faucet) apiHandler(conn *websocket.Conn) {
nonce
uint64
err
error
)
for
{
// Attempt to retrieve the stats, may error on no faucet connectivity
ctx
,
cancel
:=
context
.
WithTimeout
(
context
.
Background
(),
3
*
time
.
Second
)
head
,
err
=
f
.
client
.
HeaderByNumber
(
ctx
,
nil
)
if
err
==
nil
{
balance
,
err
=
f
.
client
.
BalanceAt
(
ctx
,
f
.
account
.
Address
,
head
.
Number
)
if
err
==
nil
{
nonce
,
err
=
f
.
client
.
NonceAt
(
ctx
,
f
.
account
.
Address
,
nil
)
for
head
==
nil
||
balance
==
nil
{
// Retrieve the current stats cached by the faucet
f
.
lock
.
RLock
()
if
f
.
head
!=
nil
{
head
=
types
.
CopyHeader
(
f
.
head
)
}
if
f
.
balance
!=
nil
{
balance
=
new
(
big
.
Int
)
.
Set
(
f
.
balance
)
}
cancel
()
nonce
=
f
.
nonce
f
.
lock
.
RUnlock
()
// If stats retrieval failed, wait a bit and retry
if
err
!=
nil
{
if
err
=
sendError
(
conn
,
errors
.
New
(
"Faucet offline
: "
+
err
.
Error
()
));
err
!=
nil
{
if
head
==
nil
||
balance
==
nil
{
// Report the faucet offline until initial stats are ready
if
err
=
sendError
(
conn
,
errors
.
New
(
"Faucet offline
"
));
err
!=
nil
{
log
.
Warn
(
"Failed to send faucet error to client"
,
"err"
,
err
)
return
}
time
.
Sleep
(
3
*
time
.
Second
)
continue
}
// Initial stats reported successfully, proceed with user interaction
break
}
// Send over the initial stats and the latest header
if
err
=
send
(
conn
,
map
[
string
]
interface
{}{
"funds"
:
balance
.
Div
(
balance
,
ether
),
"funds"
:
new
(
big
.
Int
)
.
Div
(
balance
,
ether
),
"funded"
:
nonce
,
"peers"
:
f
.
stack
.
Server
()
.
PeerCount
(),
"requests"
:
f
.
reqs
,
...
...
@@ -520,6 +519,47 @@ func (f *faucet) apiHandler(conn *websocket.Conn) {
}
}
// refresh attempts to retrieve the latest header from the chain and extract the
// associated faucet balance and nonce for connectivity caching.
func
(
f
*
faucet
)
refresh
(
head
*
types
.
Header
)
error
{
// Ensure a state update does not run for too long
ctx
,
cancel
:=
context
.
WithTimeout
(
context
.
Background
(),
5
*
time
.
Second
)
defer
cancel
()
// If no header was specified, use the current chain head
var
err
error
if
head
==
nil
{
if
head
,
err
=
f
.
client
.
HeaderByNumber
(
ctx
,
nil
);
err
!=
nil
{
return
err
}
}
// Retrieve the balance, nonce and gas price from the current head
var
(
balance
*
big
.
Int
nonce
uint64
price
*
big
.
Int
)
if
balance
,
err
=
f
.
client
.
BalanceAt
(
ctx
,
f
.
account
.
Address
,
head
.
Number
);
err
!=
nil
{
return
err
}
if
nonce
,
err
=
f
.
client
.
NonceAt
(
ctx
,
f
.
account
.
Address
,
head
.
Number
);
err
!=
nil
{
return
err
}
if
price
,
err
=
f
.
client
.
SuggestGasPrice
(
ctx
);
err
!=
nil
{
return
err
}
// Everything succeeded, update the cached stats and eject old requests
f
.
lock
.
Lock
()
f
.
head
,
f
.
balance
=
head
,
balance
f
.
price
,
f
.
nonce
=
price
,
nonce
for
len
(
f
.
reqs
)
>
0
&&
f
.
reqs
[
0
]
.
Tx
.
Nonce
()
<
f
.
nonce
{
f
.
reqs
=
f
.
reqs
[
1
:
]
}
f
.
lock
.
Unlock
()
return
nil
}
// loop keeps waiting for interesting events and pushes them out to connected
// websockets.
func
(
f
*
faucet
)
loop
()
{
...
...
@@ -537,45 +577,27 @@ func (f *faucet) loop() {
go
func
()
{
for
head
:=
range
update
{
// New chain head arrived, query the current stats and stream to clients
var
(
balance
*
big
.
Int
nonce
uint64
price
*
big
.
Int
err
error
)
ctx
,
cancel
:=
context
.
WithTimeout
(
context
.
Background
(),
5
*
time
.
Second
)
balance
,
err
=
f
.
client
.
BalanceAt
(
ctx
,
f
.
account
.
Address
,
head
.
Number
)
if
err
==
nil
{
nonce
,
err
=
f
.
client
.
NonceAt
(
ctx
,
f
.
account
.
Address
,
nil
)
if
err
==
nil
{
price
,
err
=
f
.
client
.
SuggestGasPrice
(
ctx
)
}
timestamp
:=
time
.
Unix
(
head
.
Time
.
Int64
(),
0
)
if
time
.
Since
(
timestamp
)
>
time
.
Hour
{
log
.
Warn
(
"Skipping faucet refresh, head too old"
,
"number"
,
head
.
Number
,
"hash"
,
head
.
Hash
(),
"age"
,
common
.
PrettyAge
(
timestamp
))
continue
}
cancel
()
// If querying the data failed, try for the next block
if
err
!=
nil
{
if
err
:=
f
.
refresh
(
head
);
err
!=
nil
{
log
.
Warn
(
"Failed to update faucet state"
,
"block"
,
head
.
Number
,
"hash"
,
head
.
Hash
(),
"err"
,
err
)
continue
}
else
{
log
.
Info
(
"Updated faucet state"
,
"block"
,
head
.
Number
,
"hash"
,
head
.
Hash
(),
"balance"
,
balance
,
"nonce"
,
nonce
,
"price"
,
price
)
}
// Faucet state retrieved, update locally and send to clients
balance
=
new
(
big
.
Int
)
.
Div
(
balance
,
ether
)
f
.
lock
.
RLock
()
log
.
Info
(
"Updated faucet state"
,
"number"
,
head
.
Number
,
"hash"
,
head
.
Hash
(),
"age"
,
common
.
PrettyAge
(
timestamp
),
"balance"
,
f
.
balance
,
"nonce"
,
f
.
nonce
,
"price"
,
f
.
price
)
f
.
lock
.
Lock
()
f
.
price
,
f
.
nonce
=
price
,
nonce
for
len
(
f
.
reqs
)
>
0
&&
f
.
reqs
[
0
]
.
Tx
.
Nonce
()
<
f
.
nonce
{
f
.
reqs
=
f
.
reqs
[
1
:
]
}
f
.
lock
.
Unlock
()
balance
:=
new
(
big
.
Int
)
.
Div
(
f
.
balance
,
ether
)
peers
:=
f
.
stack
.
Server
()
.
PeerCount
()
f
.
lock
.
RLock
()
for
_
,
conn
:=
range
f
.
conns
{
if
err
:=
send
(
conn
,
map
[
string
]
interface
{}{
"funds"
:
balance
,
"funded"
:
f
.
nonce
,
"peers"
:
f
.
stack
.
Server
()
.
PeerCount
()
,
"peers"
:
peers
,
"requests"
:
f
.
reqs
,
},
time
.
Second
);
err
!=
nil
{
log
.
Warn
(
"Failed to send stats to client"
,
"err"
,
err
)
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment