Skip to content
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

Benchmark/performances for the executions #1570

Closed
antho1404 opened this issue Dec 19, 2019 · 2 comments · Fixed by #1636
Closed

Benchmark/performances for the executions #1570

antho1404 opened this issue Dec 19, 2019 · 2 comments · Fixed by #1636
Assignees
Labels
enhancement New feature or request

Comments

@antho1404
Copy link
Member

When trying to fix #1537 I realized that with the current configuration we were only capable of processing 4-5 transactions per block.

This can come from 2 problems:

  • we reach the block capacity, either with the size of the messages (which I doubt) or the number of gas spent (more likely)
  • the processing/validation before adding in the pool of transaction takes a lot of time and we can only sign/broadcast ~4 transactions per seconds (current block time)

We have a huge bottleneck somewhere, I think because we try to send the transactions in a synchronous way. I have high doubts that this is just because of pure processing like hashing functions or so but it might be something to explore too.


I tried to increase the block time to 10 seconds and it seems that we can process about 20-25 transactions (with similar executions message) so it seems that the problem doesn't come from the capacity of the block.

@antho1404 antho1404 added the enhancement New feature or request label Dec 19, 2019
@antho1404
Copy link
Member Author

I run a bunch of tests to try to understand the bottleneck issue that we have

Tests

Run the process of this repository https://github.com/antho1404/application-erc20-analytics
You can monitor the metrics with this branch/PR #1580

Results

We always the same kind of results

  • Execution created and pre-signed immediately
  • Execution signed with a delay (blue curve)
  • Execution in progress connected to tx signed until a certain point where it stops
  • Execution completed caped by the executions in progress

It seems that there is a correlation between the transaction signed (blue) and the transaction completed (red) but that doesn’t impact the transaction in progress

The signature/broadcast of the transaction is clearly a bottleneck that needs to be fixed

Screen Shot 2020-01-03 at 21 17 08

@NicolasMahe NicolasMahe added this to To do in Sprint weeks 2 & 3 via automation Jan 10, 2020
@NicolasMahe NicolasMahe moved this from To do to In progress in Sprint weeks 2 & 3 Jan 10, 2020
@NicolasMahe NicolasMahe removed this from In progress in Sprint weeks 2 & 3 Jan 28, 2020
@NicolasMahe NicolasMahe added this to To do in Sprint weeks 4 & 5 via automation Jan 28, 2020
@NicolasMahe
Copy link
Member

Source code that should be the source of the problem for the slowness of signing / broadcasting:

engine/cosmos/client.go

Lines 84 to 128 in 47b743e

// BuildAndBroadcastMsg builds and signs message and broadcast it to node.
func (c *Client) BuildAndBroadcastMsg(msg sdktypes.Msg) (*abci.ResponseDeliverTx, error) {
c.broadcastMutex.Lock() // Lock the whole signature + broadcast of the transaction
signedTx, err := c.sign(msg)
if err != nil {
c.broadcastMutex.Unlock()
return nil, err
}
txres, err := c.BroadcastTxSync(signedTx)
c.broadcastMutex.Unlock()
if err != nil {
return nil, err
}
if txres.Code != abci.CodeTypeOK {
return nil, fmt.Errorf("transaction returned with invalid code %d", txres.Code)
}
// TODO: 20*time.Second should not be hardcoded here
ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second)
defer cancel()
subscriber := "engine"
query := tenderminttypes.EventQueryTxFor(signedTx).String()
out, err := c.Subscribe(ctx, subscriber, query)
if err != nil {
return nil, err
}
defer c.Unsubscribe(ctx, subscriber, query)
select {
case result := <-out:
data, ok := result.Data.(tenderminttypes.EventDataTx)
if !ok {
return nil, errors.New("result data is not the right type")
}
if data.TxResult.Result.IsErr() {
return nil, fmt.Errorf("an error occurred in transaction: %s", data.TxResult.Result.Log)
}
return &data.TxResult.Result, nil
case <-ctx.Done():
return nil, errors.New("i/o timeout")
}
}

  • TODO: implement the mutex in a much more clever way

Extracting the account and signature logic to a dedicated structure can only help. Started in PR #1573 because of issue #1565

Two attempts to create benchmark on the whole API:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
No open projects
Development

Successfully merging a pull request may close this issue.

3 participants