-
Notifications
You must be signed in to change notification settings - Fork 1
NonStop from Pascal to Lorentz HF #57
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
Changes from 30 commits
5ecb517
ed20939
c83c2c8
575183f
65c004b
22061b2
5a52263
b75adf5
2b2a875
b9e0fac
b4dc6be
8f859c3
219ad16
f3b05b2
5824ec7
c9a4f43
bd5b4cf
f8e2d54
1b8d38e
0da2a4b
d1ab860
a9bbd78
b7c1a28
38284e6
77bce51
c39dccb
e341b90
f37a183
7a54feb
e232ac1
7a25445
49dcb36
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,14 @@ | ||
| package module | ||
|
|
||
| import ( | ||
| "context" | ||
| "fmt" | ||
| "github.com/hyperledger-labs/yui-relayer/log" | ||
| "math" | ||
| "os" | ||
| "strconv" | ||
| ) | ||
|
|
||
| type Network string | ||
|
|
||
| const ( | ||
|
|
@@ -8,29 +17,229 @@ const ( | |
| Mainnet Network = "mainnet" | ||
| ) | ||
|
|
||
| var localLorentzHF isForkSpec_HeightOrTimestamp = &ForkSpec_Height{Height: 1} | ||
|
|
||
| func init() { | ||
| localLorentzHFTimestamp := os.Getenv("LOCAL_LORENTZ_HF_TIMESTAMP") | ||
| if localLorentzHFTimestamp != "" { | ||
| result, err := strconv.Atoi(localLorentzHFTimestamp) | ||
| if err != nil { | ||
| panic(err) | ||
| } | ||
| localLorentzHF = &ForkSpec_Timestamp{Timestamp: uint64(result)} | ||
| } | ||
| } | ||
|
|
||
| func GetForkParameters(network Network) []*ForkSpec { | ||
| switch network { | ||
| case Localnet: | ||
| return []*ForkSpec{ | ||
| // Pascal HF | ||
| { | ||
| HeightOrTimestamp: &ForkSpec_Timestamp{Timestamp: 0}, | ||
| // Must Set Milli timestamp | ||
| HeightOrTimestamp: &ForkSpec_Height{Height: 0}, | ||
| AdditionalHeaderItemCount: 1, | ||
| EpochLength: 200, | ||
| MaxTurnLength: 9, | ||
| }, | ||
| // Lorentz HF | ||
| { | ||
| // Must Set Milli timestamp | ||
| HeightOrTimestamp: localLorentzHF, | ||
| AdditionalHeaderItemCount: 1, | ||
| EpochLength: 500, | ||
| MaxTurnLength: 64, | ||
| }, | ||
| } | ||
| case Testnet: | ||
| return []*ForkSpec{ | ||
| { | ||
| HeightOrTimestamp: &ForkSpec_Timestamp{Timestamp: 0}, | ||
| // https://forum.bnbchain.org/t/bnb-chain-upgrades-testnet/934 | ||
| HeightOrTimestamp: &ForkSpec_Height{Height: 48576786}, | ||
| AdditionalHeaderItemCount: 1, | ||
| EpochLength: 200, | ||
| MaxTurnLength: 9, | ||
| }, | ||
| { | ||
| HeightOrTimestamp: &ForkSpec_Timestamp{Timestamp: math.MaxUint64}, | ||
| AdditionalHeaderItemCount: 1, | ||
| EpochLength: 500, | ||
| MaxTurnLength: 64, | ||
| }, | ||
| } | ||
| case Mainnet: | ||
| return []*ForkSpec{ | ||
| { | ||
| HeightOrTimestamp: &ForkSpec_Timestamp{Timestamp: 0}, | ||
| // https://bscscan.com/block/47618307 | ||
| // https://github.com/bnb-chain/bsc/releases/tag/v1.5.7 | ||
| HeightOrTimestamp: &ForkSpec_Height{Height: 47618307}, | ||
| AdditionalHeaderItemCount: 1, | ||
| EpochLength: 200, | ||
| MaxTurnLength: 9, | ||
| }, | ||
| { | ||
| HeightOrTimestamp: &ForkSpec_Timestamp{Timestamp: math.MaxUint64}, | ||
| AdditionalHeaderItemCount: 1, | ||
| EpochLength: 500, | ||
| MaxTurnLength: 64, | ||
| }, | ||
| } | ||
| } | ||
| return nil | ||
| } | ||
|
|
||
| type BoundaryEpochs struct { | ||
| PreviousForkSpec ForkSpec | ||
| CurrentForkSpec ForkSpec | ||
| BoundaryHeight uint64 | ||
| PrevLast uint64 | ||
| CurrentFirst uint64 | ||
| Intermediates []uint64 | ||
| } | ||
|
|
||
| type BoundaryHeight struct { | ||
| Height uint64 | ||
| CurrentForkSpec ForkSpec | ||
| } | ||
|
|
||
| func (b BoundaryHeight) GetBoundaryEpochs(prevForkSpec ForkSpec) (*BoundaryEpochs, error) { | ||
| boundaryHeight := b.Height | ||
| prevLast := boundaryHeight - (boundaryHeight % prevForkSpec.EpochLength) | ||
| index := uint64(0) | ||
| currentFirst := uint64(0) | ||
| for { | ||
| candidate := boundaryHeight + index | ||
| if candidate%b.CurrentForkSpec.EpochLength == 0 { | ||
| currentFirst = candidate | ||
| break | ||
| } | ||
| index++ | ||
| } | ||
| intermediates := make([]uint64, 0) | ||
| // starts 0, 200, 400...epoch_length | ||
| if prevLast == 0 { | ||
| const defaultEpochLength = 200 | ||
| for mid := prevLast + defaultEpochLength; mid < prevForkSpec.EpochLength; mid += defaultEpochLength { | ||
| intermediates = append(intermediates, mid) | ||
| } | ||
| } | ||
| for mid := prevLast + prevForkSpec.EpochLength; mid < currentFirst; mid += prevForkSpec.EpochLength { | ||
| intermediates = append(intermediates, mid) | ||
| } | ||
|
|
||
| return &BoundaryEpochs{ | ||
| PreviousForkSpec: prevForkSpec, | ||
| CurrentForkSpec: b.CurrentForkSpec, | ||
| BoundaryHeight: boundaryHeight, | ||
| PrevLast: prevLast, | ||
| CurrentFirst: currentFirst, | ||
| Intermediates: intermediates, | ||
| }, nil | ||
| } | ||
|
|
||
| func (be BoundaryEpochs) CurrentEpochBlockNumber(number uint64) uint64 { | ||
| if number >= be.CurrentFirst { | ||
| return number - (number % be.CurrentForkSpec.EpochLength) | ||
| } | ||
|
|
||
| if len(be.Intermediates) > 0 { | ||
| for i := len(be.Intermediates) - 1; i >= 0; i-- { | ||
| if number >= be.Intermediates[i] { | ||
| return be.Intermediates[i] | ||
| } | ||
| } | ||
| } | ||
| return number - (number % be.PreviousForkSpec.EpochLength) | ||
| } | ||
|
|
||
| func (be BoundaryEpochs) PreviousEpochBlockNumber(currentEpochBlockNumber uint64) uint64 { | ||
| if currentEpochBlockNumber == 0 { | ||
| return 0 | ||
| } | ||
| if currentEpochBlockNumber <= be.PrevLast { | ||
| return currentEpochBlockNumber - be.PreviousForkSpec.EpochLength | ||
| } | ||
|
|
||
| for i, mid := range be.Intermediates { | ||
| if currentEpochBlockNumber == mid { | ||
| if i == 0 { | ||
| return be.PrevLast | ||
| } | ||
| return be.Intermediates[i-1] | ||
| } | ||
| } | ||
|
|
||
| if currentEpochBlockNumber == be.CurrentFirst { | ||
| if len(be.Intermediates) == 0 { | ||
| return be.PrevLast | ||
| } | ||
| return be.Intermediates[len(be.Intermediates)-1] | ||
| } | ||
|
|
||
| return currentEpochBlockNumber - be.CurrentForkSpec.EpochLength | ||
| } | ||
|
|
||
| func FindTargetForkSpec(forkSpecs []*ForkSpec, height uint64, timestamp uint64) (*ForkSpec, *ForkSpec, error) { | ||
| reversed := make([]*ForkSpec, len(forkSpecs)) | ||
| for i, spec := range forkSpecs { | ||
| reversed[len(forkSpecs)-i-1] = spec | ||
| } | ||
|
|
||
| getPrev := func(current *ForkSpec, i int) *ForkSpec { | ||
| if i == len(reversed)-1 { | ||
| return current | ||
| } | ||
| return reversed[i+1] | ||
| } | ||
|
|
||
| for i, spec := range reversed { | ||
| if x, ok := spec.GetHeightOrTimestamp().(*ForkSpec_Height); ok { | ||
| if x.Height <= height { | ||
| return spec, getPrev(spec, i), nil | ||
| } | ||
| } else { | ||
| if spec.GetTimestamp() <= timestamp { | ||
| return spec, getPrev(spec, i), nil | ||
| } | ||
| } | ||
| } | ||
| return nil, nil, fmt.Errorf("no fork spec found height=%d, timestmp=%d", height, timestamp) | ||
| } | ||
|
|
||
| var boundaryHeightCache = make(map[uint64]uint64) | ||
|
|
||
| func GetBoundaryHeight(headerFn getHeaderFn, currentHeight uint64, currentForkSpec ForkSpec) (*BoundaryHeight, error) { | ||
| logger := log.GetLogger() | ||
| boundaryHeight := uint64(0) | ||
| if condition, ok := currentForkSpec.GetHeightOrTimestamp().(*ForkSpec_Height); ok { | ||
| boundaryHeight = condition.Height | ||
| } else { | ||
| ts := currentForkSpec.GetTimestamp() | ||
| if v, ok := boundaryHeightCache[ts]; ok { | ||
| boundaryHeight = v | ||
| } else { | ||
| logger.Debug("seek fork height", "currentHeight", currentHeight, "ts", ts) | ||
| for i := int64(currentHeight); i >= 0; i-- { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Optional optimization: Consider estimating heights near hardfork points using ForkSpec's block generation time to reduce header query overhead. This isn't a required fix but could improve performance for post-hardfork requests.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It will be supported after the next version release. There is a grace period until the next Maxwell HF. |
||
| h, err := headerFn(context.Background(), uint64(i)) | ||
| if err != nil { | ||
| return nil, err | ||
3100 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| } | ||
| if MilliTimestamp(h) == ts { | ||
| boundaryHeight = h.Number.Uint64() | ||
| logger.Debug("seek fork height found", "currentHeight", currentHeight, "ts", ts, "boundaryHeight", boundaryHeight) | ||
| boundaryHeightCache[ts] = boundaryHeight | ||
| break | ||
| } else if MilliTimestamp(h) < ts { | ||
| boundaryHeight = h.Number.Uint64() + 1 | ||
| logger.Debug("seek fork height found", "currentHeight", currentHeight, "ts", ts, "boundaryHeight", boundaryHeight) | ||
| boundaryHeightCache[ts] = boundaryHeight | ||
| break | ||
| } | ||
| } | ||
| } | ||
| } | ||
| return &BoundaryHeight{ | ||
| Height: boundaryHeight, | ||
| CurrentForkSpec: currentForkSpec, | ||
| }, nil | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.