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

Convert the type of Quota and QuotaUsed from big.Int to uint64 #654

Merged
merged 9 commits into from
Jul 7, 2020

Conversation

DhunterAO
Copy link
Contributor

  1. The uint64 type introduce the risk of overflow, so I add checks after add and sub operations, please check whether they are correct or if there are some checks missed.
  2. The update of storage may cause hard fork of the blockchain, so I only update the type in the memory layer and keep the big.Int in storage layer. Please check whether there is any code in storage influnced.

@@ -301,7 +301,7 @@ func (cuckoo *Cuckoo) verifyHeader(chain consensus.ChainReader, header, parent *
return consensus.ErrInvalidNumber
}

if header.Quota.Cmp(new(big.Int).Add(parent.Quota, new(big.Int).SetUint64(chain.Config().GetBlockQuota(header.Number)))) != 0 {
if header.Quota < parent.Quota || header.Quota != parent.Quota+chain.Config().GetBlockQuota(header.Number) {
Copy link
Member

Choose a reason for hiding this comment

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

Whether the second condition contains first one?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The first one consider the overflow of uint64.
For example, parent.Quota = MaxUint64 - 1, blockQuota = 2, header.Quota = 1. This situation satisfies the second condition but dissatisfies the first one.

Copy link
Member

Choose a reason for hiding this comment

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

Can quota reach MaxUint64, we should avoid overflow in quota calculation.
In fact we can calculate when the quota limit will be

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, gasLimit is set for each block own, but the quota is accumulated through the whole blockchain.
For the max quota value in each block is 65536 * 128 (for dolores), which means the limit will be reached at block number 2199023255551

Copy link
Member

@ucwong ucwong Jul 4, 2020

Choose a reason for hiding this comment

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

Yes, gas limit from big.int to uint64 because they know the ceiling ethereum/go-ethereum@6f69cdd#diff-afbbe5ab9727e568254cfee647e62876

2199023255551 is huge for block number, should we consider it as ∞ ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

If we can consider it as ∞, I think we can also convert the quota into uint64

header.QuotaUsed = new(big.Int).Set(parent.QuotaUsed)
header.Quota = parent.Quota + chain.Config().GetBlockQuota(header.Number)
if header.Quota < parent.Quota {
panic("quota reaches the upper limit of uint64")
Copy link
Member

@ucwong ucwong Jul 4, 2020

Choose a reason for hiding this comment

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

Is there any possible to be panic here, if there is, big.Int should be more suitable

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Due to the consideration of overflow, if the result of addition exceeds the max of uint64, the panic will occur.
If the type is big.Int, it seems to be unlimited.

Copy link
Member

Choose a reason for hiding this comment

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

Yes, the big.Int is used for avoid overflow. If it can be overflow , big.Int should be suitable for quota

Copy link
Member

@ucwong ucwong Jul 4, 2020

Choose a reason for hiding this comment

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

If a valiate block satisfy this condition occurs, all the nodes will crash.

Copy link
Member

Choose a reason for hiding this comment

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

we should confirm all the panics in code can't be attacked.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

In fact, I just test that the addition overflow will panic automatically in Golang. Not like that in C/C++. So we need to do the check before to prevent the panics.

@codecov
Copy link

codecov bot commented Jul 4, 2020

Codecov Report

Merging #654 into master will decrease coverage by 0.01%.
The diff coverage is 26.31%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #654      +/-   ##
==========================================
- Coverage   50.85%   50.84%   -0.02%     
==========================================
  Files         405      407       +2     
  Lines       51727    51755      +28     
==========================================
+ Hits        26308    26316       +8     
- Misses      23405    23415      +10     
- Partials     2014     2024      +10     
Impacted Files Coverage Δ
common/math/min.go 0.00% <0.00%> (ø)
consensus/cuckoo/consensus.go 1.71% <0.00%> (-0.01%) ⬇️
core/blockchain_insert.go 79.31% <ø> (ø)
core/state_prefetcher.go 34.37% <0.00%> (-2.30%) ⬇️
core/types/block.go 25.60% <0.00%> (+0.60%) ⬆️
core/types/gen_header_json.go 0.00% <0.00%> (ø)
ctxc/api_tracer.go 0.00% <0.00%> (ø)
core/state_transition.go 49.35% <26.66%> (ø)
core/state_processor.go 67.85% <33.33%> (-2.52%) ⬇️
core/quotapool.go 38.88% <38.88%> (ø)
... and 13 more


st.state.SubUpload(st.to(), quota) //64 ~ 1024 bytes
st.state.SubUpload(st.to(), big.NewInt(int64(quota))) //64 ~ 1024 bytes
Copy link
Member

@ucwong ucwong Jul 4, 2020

Choose a reason for hiding this comment

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

big.NewInt(0).SetUint64(value)
The upload also can be changed to uint64 for it should always below the quota, but it maybe complex, we will think about it in the future

Copy link
Contributor Author

Choose a reason for hiding this comment

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

got it

Copy link
Contributor Author

Choose a reason for hiding this comment

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

got it

@ucwong
Copy link
Member

ucwong commented Jul 4, 2020

Did you use go generate to generate code like gen_*

@DhunterAO
Copy link
Contributor Author

Did you use go generate to generate code like gen_*

I havn't installed the gencodec, so just modify the gen_header_json.go manually.

@ucwong
Copy link
Member

ucwong commented Jul 4, 2020

It's great, what we should think about is the overflow of uint64 in this situation

@ucwong
Copy link
Member

ucwong commented Jul 4, 2020

I have built it and let it keep running for some days and see the metrics chart

@DhunterAO
Copy link
Contributor Author

got it

@ucwong
Copy link
Member

ucwong commented Jul 4, 2020

@ucwong
Copy link
Member

ucwong commented Jul 6, 2020

image
Before and after this PR to fully sync blockchain (alloc/s)

@ucwong ucwong self-requested a review July 7, 2020 06:41
Copy link
Member

@ucwong ucwong left a comment

Choose a reason for hiding this comment

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

LGTM

@ucwong ucwong merged commit 259994e into master Jul 7, 2020
@DhunterAO
Copy link
Contributor Author

image
Before and after this PR to fully sync blockchain (alloc/s)

Looks cool. I wonder what each color means? Does this PR increase the alloc number per second?

@ucwong
Copy link
Member

ucwong commented Jul 7, 2020

image
Before and after this PR to fully sync blockchain (alloc/s)

Looks cool. I wonder what each color means? Does this PR increase the alloc number per second?

image
Different scopes 1m 5m 15m and mean

@DhunterAO DhunterAO deleted the uint64Quota branch July 7, 2020 09:22
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

2 participants