Skip to content

Commit

Permalink
Add rate-limiter (#7)
Browse files Browse the repository at this point in the history
* Add rate limiter

* Refuse to update state without new inclusion

* Address comments

* Address comment
  • Loading branch information
rjl493456442 committed Apr 5, 2020
1 parent f7892b9 commit b928fe7
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 1 deletion.
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ require (
github.com/INFURA/go-ethlibs v0.0.0-20190906161005-7045fb26c40c
github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89
github.com/umbracle/go-web3 v0.0.0-20200107141429-b044b1dc2479
golang.org/x/time v0.0.0-20191024005414-555d28b269f0
)
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,8 @@ golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0 h1:/5xXl8Y5W96D+TtHSlonuFqGHIWVuyCkGJLwGh9JJFs=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U=
Expand Down
20 changes: 20 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (

"github.com/INFURA/go-ethlibs/node"
flags "github.com/jessevdk/go-flags"
"golang.org/x/time/rate"
)

// Version of the binary, assigned during build.
Expand All @@ -21,6 +22,7 @@ var Version = "dev"
type Options struct {
Methods map[string]int64 `short:"m" long:"method" description:"A map from json rpc methods to their weight" default:"eth_getCode:100" default:"eth_getLogs:250" default:"eth_getTransactionByHash:250" default:"eth_blockNumber:350" default:"eth_getTransactionCount:400" default:"eth_getBlockByNumber:400" default:"eth_getBalance:550" default:"eth_getTransactionReceipt:600" default:"eth_call:2000"`
Web3Endpoint string `long:"rpc" description:"Ethereum JSONRPC provider, such as Infura or Cloudflare" default:"https://mainnet.infura.io/v3/af500e495f2d4e7cbcae36d0bfa66bcb"` // Versus API key on Infura
RateLimit float64 `short:"r" long:"ratelimit" description:"rate limit for generating jsonrpc calls"`

Version bool `long:"version" description:"Print version and exit."`
}
Expand Down Expand Up @@ -75,6 +77,17 @@ func main() {
for {
newState, err := mkState.Refresh(&state)
if err != nil {
// It can happen in some testnets that most of the blocks
// are empty(no transaction included), don't refresh the
// generator state without new inclusion.
if err == errEmptyBlock {
select {
case <-time.After(5 * time.Second):
case <-ctx.Done():
return
}
continue
}
exit(2, "failed to refresh state")
}
select {
Expand All @@ -90,6 +103,10 @@ func main() {
}
}()

var rlimit *rate.Limiter
if options.RateLimit != 0 {
rlimit = rate.NewLimiter(rate.Limit(options.RateLimit), 10)
}
state := <-stateChannel
for {
// Update state when a new one is emitted
Expand All @@ -99,6 +116,9 @@ func main() {
return
default:
}
if rlimit != nil {
rlimit.Wait(context.Background())
}
if err := gen.Query(os.Stdout, state); err == io.EOF {
// Done
return
Expand Down
7 changes: 6 additions & 1 deletion state.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import (
"github.com/INFURA/go-ethlibs/node"
)

var errEmptyBlock = errors.New("the sampled block is empty")

type State interface {
RandInt64() int64
ID() int64
Expand Down Expand Up @@ -130,7 +132,10 @@ func (p *stateProducer) Refresh(oldState *liveState) (*liveState, error) {
if err != nil {
return nil, err
}

// Short circuit if the sampled block is empty
if len(b.Transactions) == 0 {
return nil, errEmptyBlock
}
// txs will grow to the maximum contract transaction list size we'll see in a block, and the higher-indexed ones will stick around longer
txs := oldState.transactions
for i, tx := range b.Transactions {
Expand Down

0 comments on commit b928fe7

Please sign in to comment.