erigon-pulse/params/eip_ctx.go

166 lines
3.8 KiB
Go

package params
import (
"context"
"math/big"
)
type configKey int
const (
IsHomesteadEnabled configKey = iota
IsEIP150Enabled
IsEIP155Enabled
IsEIP158Enabled
IsEIP2027Enabled
IsByzantiumEnabled
IsConstantinopleEnabled
IsPetersburgEnabled
IsEWASM
BlockNumber
NoHistory
WithHistoryHighest
)
func (c *ChainConfig) WithEIPsFlags(ctx context.Context, blockNum *big.Int) context.Context {
ctx = context.WithValue(ctx, IsHomesteadEnabled, c.IsHomestead(blockNum))
ctx = context.WithValue(ctx, IsEIP150Enabled, c.IsEIP150(blockNum))
ctx = context.WithValue(ctx, IsEIP155Enabled, c.IsEIP155(blockNum))
ctx = context.WithValue(ctx, IsEIP158Enabled, c.IsEIP158(blockNum))
ctx = context.WithValue(ctx, IsEIP2027Enabled, c.IsEIP2027(blockNum))
ctx = context.WithValue(ctx, IsByzantiumEnabled, c.IsByzantium(blockNum))
ctx = context.WithValue(ctx, IsConstantinopleEnabled, c.IsConstantinople(blockNum))
ctx = context.WithValue(ctx, IsPetersburgEnabled, c.IsPetersburg(blockNum))
ctx = context.WithValue(ctx, IsEWASM, c.IsEWASM(blockNum))
ctx = context.WithValue(ctx, BlockNumber, blockNum)
return ctx
}
func WithNoHistory(ctx context.Context, defaultValue bool, f noHistFunc) context.Context {
return context.WithValue(ctx, NoHistory, getIsNoHistory(defaultValue, f))
}
func GetForkFlag(ctx context.Context, name configKey) bool {
b := ctx.Value(name)
if b == nil {
return false
}
if valB, ok := b.(bool); ok {
return valB
}
return false
}
func GetBlockNumber(ctx context.Context) *big.Int {
b := ctx.Value(BlockNumber)
if b == nil {
return nil
}
if valB, ok := b.(*big.Int); ok {
return valB
}
return nil
}
func GetNoHistoryByBlock(ctx context.Context, currentBlock *big.Int) (context.Context, bool) {
if currentBlock == nil {
return ctx, false
}
key := getNoHistoryByBlock(currentBlock)
v, ok := getNoHistoryByKey(ctx, key)
if ok {
if !v {
ctx = updateHighestWithHistory(ctx, currentBlock)
}
return ctx, v
}
return withNoHistory(ctx, currentBlock, key)
}
func withNoHistory(ctx context.Context, currentBlock *big.Int, key configKey) (context.Context, bool) {
v := getNoHistory(ctx, currentBlock)
ctx = context.WithValue(ctx, key, v)
if !v {
ctx = updateHighestWithHistory(ctx, currentBlock)
}
return ctx, v
}
func updateHighestWithHistory(ctx context.Context, currentBlock *big.Int) context.Context {
highestWithHistory := getWithHistoryHighest(ctx)
var currentIsLower bool
if highestWithHistory != nil {
currentIsLower = currentBlock.Cmp(highestWithHistory) < 0
}
if !currentIsLower {
ctx = setWithHistoryHighestByBlock(ctx, currentBlock)
}
return ctx
}
func getNoHistory(ctx context.Context, currentBlock *big.Int) bool {
v := ctx.Value(NoHistory)
if v == nil {
return false
}
if val, ok := v.(noHistFunc); ok {
return val(currentBlock)
}
return false
}
func getWithHistoryHighest(ctx context.Context) *big.Int {
v := ctx.Value(WithHistoryHighest)
if v == nil {
return nil
}
if val, ok := v.(*big.Int); ok {
return val
}
return nil
}
func setWithHistoryHighestByBlock(ctx context.Context, block *big.Int) context.Context {
return context.WithValue(ctx, WithHistoryHighest, block)
}
func getNoHistoryByKey(ctx context.Context, key configKey) (bool, bool) {
if key < 0 {
return false, false
}
v := ctx.Value(key)
if v == nil {
return false, false
}
if val, ok := v.(bool); ok {
return val, true
}
return false, false
}
func getNoHistoryByBlock(block *big.Int) configKey {
if block == nil {
return configKey(-1)
}
return configKey(block.Uint64() + 1000)
}
func GetNoHistory(ctx context.Context) (context.Context, bool) {
return GetNoHistoryByBlock(ctx, GetBlockNumber(ctx))
}
type noHistFunc func(currentBlock *big.Int) bool
func getIsNoHistory(defaultValue bool, f noHistFunc) noHistFunc {
return func(currentBlock *big.Int) bool {
if f == nil {
return defaultValue
}
return f(currentBlock)
}
}