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

change: improve TX tracking #188

Merged
merged 10 commits into from
Jul 14, 2022
Merged

change: improve TX tracking #188

merged 10 commits into from
Jul 14, 2022

Conversation

fdymylja
Copy link
Contributor

@fdymylja fdymylja commented Jul 14, 2022

Initially TX tracking plus contracts operations were all saved into a single object.
This brings huge performance limitations and issues.

As to add 1 contract operation, you need to unmarshal one single object containing all the txs (and their respective operations) and then append to it, and then marshal it back again.

In blocks with lots of TXs this gets crazy expensive.

So this PR puts every tx tracking information into its own object.

This could be better improved by putting every single operation into its own object and doing all the connections when the block tracking info is fetched. Leaving this for another PR to reduce the scope.

On top of that it also removes copied test utilities.

@fdymylja fdymylja marked this pull request as draft July 14, 2022 11:40
@codecov
Copy link

codecov bot commented Jul 14, 2022

Codecov Report

Merging #188 (bbef6ff) into main (db41026) will increase coverage by 1.80%.
The diff coverage is 97.67%.

@@            Coverage Diff             @@
##             main     #188      +/-   ##
==========================================
+ Coverage   56.86%   58.66%   +1.80%     
==========================================
  Files          17       17              
  Lines        1224     1200      -24     
==========================================
+ Hits          696      704       +8     
+ Misses        483      460      -23     
+ Partials       45       36       -9     
Impacted Files Coverage Δ
x/gastracker/keeper/grpc_query.go 0.00% <0.00%> (ø)
x/gastracker/ante/ante.go 100.00% <100.00%> (ø)
x/gastracker/keeper/keeper.go 95.45% <100.00%> (+16.73%) ⬆️
...gastracker/keeper/keeper_contract_gas_processor.go 61.36% <100.00%> (+1.81%) ⬆️
x/gastracker/module/abci.go 81.60% <100.00%> (+2.22%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update db41026...bbef6ff. Read the comment docs.

@fdymylja fdymylja marked this pull request as ready for review July 14, 2022 12:27
Copy link
Contributor

@iTiky iTiky left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

for ; iter.Valid(); iter.Next() {
v := gastracker.TransactionTracking{}
k.cdc.MustUnmarshal(iter.Value(), &v)
log.Printf("%s", &v)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No God please no 😁

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

whoops :D

@@ -116,7 +107,7 @@ func TestGasTrackingAnteHandler(t *testing.T) {
"Gastracking ante handler should not return an error",
)

currentBlockTrackingInfo, err := keeper.GetCurrentBlockTracking(ctx)
currentBlockTrackingInfo := keeper.GetCurrentBlockTracking(ctx)
assert.NoError(t, err, "Current block tracking info should exists")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should probably remove this assert


bytes := store.Get(key)
if bytes == nil {
panic(fmt.Errorf("no gas tracking found for tx"))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Panics are very dangerous to runtime and health of the process, are we sure we shouldn't just return an error?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will comment this, but it must yield a panic

Copy link
Contributor

@ParthDesai ParthDesai left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While tracking new block, you will be iterating through all tx objects and removing them. This iteration as well deletion costs more disk I/O since the data may be at different sectors of disk compared to if entire data is stored in one place.

Better approach here would be to cache the entire block tracking object in memory if possible.

@edjroz
Copy link
Contributor

edjroz commented Jul 14, 2022

While tracking new block, you will be iterating through all tx objects and removing them. This iteration as well deletion costs more disk I/O since the data may be at different sectors of disk compared to if entire data is stored in one place.

Better approach here would be to cache the entire block tracking object in memory if possible.

This can be looked and considered as an upgrade, It's hard to predict Disk I/O performance since there are multiple factors at play from DB being used to OS optimizations and Filesystems.

If need be we could look into a cache solution but this in itself is likely to yield it's own cost in both technical debt and performance given the behavior of the Golang GC.

@fdymylja
Copy link
Contributor Author

fdymylja commented Jul 14, 2022

While tracking new block, you will be iterating through all tx objects and removing them. This iteration as well deletion costs more disk I/O since the data may be at different sectors of disk compared to if entire data is stored in one place.
Better approach here would be to cache the entire block tracking object in memory if possible.

Performance should improve in this PR, before adding one contract operation meant fully decoding the block, its transactions, and each transaction's operations, appending info and then encoding everything back into state.

As TX number grows, alongside contract interactions, this would have been extremely more expensive than what I have implemented here.

Also, with regards to caching, at this stage it is impossible unless you have full knowledge of tendermint error paths.
Since everything is cached into memory by the SDK, subcached when a TX is being executed, the sub cache reverted when TX fails, and everything is committed into the real KV once tender mint calls Commit, I would say at this stage is too much of an effort for the improvement it gives.

@fdymylja fdymylja merged commit 77e90fd into main Jul 14, 2022
@fdymylja fdymylja deleted the fdymylja/improve-tx-tracking branch July 14, 2022 15:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants