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

First goldenage fork, increasing min gas limit for contract deployment #2301

Merged
merged 1 commit into from
Oct 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions consensus/misc/statefee.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,10 @@ func CalcStateLimit(parent *types.WorkObject, stateCeil uint64) uint64 {

// If parent gas is zero and we have passed the 5 day threshold, we can set the first block gas limit to min gas limit
if parent.StateLimit() == 0 {
return params.MinGasLimit
return params.MinGasLimit(parent.NumberU64(common.ZONE_CTX))
}

parentStateLimit := parent.StateLimit()

delta := parentStateLimit/params.StateLimitBoundDivisor - 1
limit := parentStateLimit

Expand All @@ -33,7 +32,7 @@ func CalcStateLimit(parent *types.WorkObject, stateCeil uint64) uint64 {
return limit + delta
}
} else {
desiredLimit = params.MinGasLimit
desiredLimit = params.MinGasLimit(parent.NumberU64(common.ZONE_CTX))
if limit-delta/2 < desiredLimit {
return desiredLimit
} else {
Expand Down
18 changes: 16 additions & 2 deletions core/block_validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,13 @@ func (v *BlockValidator) SanityCheckWorkObjectBlockViewBody(wo *types.WorkObject
}
}
} else {
// If the fork has been triggered and within some grace period the nodes
// have not upgraded we reject the block validation
if wo.NumberU64(common.ZONE_CTX) > params.GoldenAgeForkNumberV1+params.GoldenAgeForkGraceNumber {
if wo.GasLimit() < params.MinGasLimit(params.GoldenAgeForkNumberV1) {
return fmt.Errorf("zone gas limit is less than the new fork gas limit")
}
}
if len(wo.Manifest()) != 0 {
return fmt.Errorf("zone body has non zero manifests")
}
Expand Down Expand Up @@ -270,6 +277,13 @@ func (v *BlockValidator) SanityCheckWorkObjectHeaderViewBody(wo *types.WorkObjec
}
}
} else {
// If the fork has been triggered and within some grace period the nodes
// have not upgraded we reject the block validation
if wo.NumberU64(common.ZONE_CTX) > params.GoldenAgeForkNumberV1+params.GoldenAgeForkGraceNumber {
if wo.GasLimit() < params.MinGasLimit(params.GoldenAgeForkNumberV1) {
return fmt.Errorf("zone gas limit is less than the new fork gas limit")
}
}
// Transactions, SubManifestHash, InterlinkHashes should be nil in the workshare in Zone context
if len(wo.Transactions()) != 0 {
return fmt.Errorf("zone body has non zero transactions")
Expand Down Expand Up @@ -399,7 +413,7 @@ func CalcGasLimit(parent *types.WorkObject, gasCeil uint64) uint64 {

// If parent gas is zero and we have passed the 5 day threshold, we can set the first block gas limit to min gas limit
if parent.GasLimit() == 0 {
return params.MinGasLimit
return params.MinGasLimit(parent.NumberU64(common.ZONE_CTX))
}

parentGasLimit := parent.GasLimit()
Expand All @@ -417,7 +431,7 @@ func CalcGasLimit(parent *types.WorkObject, gasCeil uint64) uint64 {
return limit + delta
}
} else {
desiredLimit = params.MinGasLimit
desiredLimit = params.MinGasLimit(parent.NumberU64(common.ZONE_CTX))
if limit-delta/2 < desiredLimit {
return desiredLimit
} else {
Expand Down
20 changes: 18 additions & 2 deletions core/chain_indexer.go
Original file line number Diff line number Diff line change
Expand Up @@ -774,7 +774,17 @@ func (c *ChainIndexer) addOutpointsToIndexer(addressOutpointsWithBlockHeight map
for _, tx := range block.Body().ExternalTransactions() {
if tx.EtxType() == types.CoinbaseType && tx.To().IsInQiLedgerScope() {
lockupByte := tx.Data()[0]
lockup := new(big.Int).SetUint64(params.LockupByteToBlockDepth[lockupByte])
// After the BigSporkFork the minimum conversion period changes to 7200 blocks
var lockup *big.Int
if lockupByte == 0 {
if block.NumberU64(common.ZONE_CTX) < params.GoldenAgeForkNumberV1 {
lockup = new(big.Int).SetUint64(params.OldConversionLockPeriod)
} else {
lockup = new(big.Int).SetUint64(params.NewConversionLockPeriod)
}
} else {
lockup = new(big.Int).SetUint64(params.LockupByteToBlockDepth[lockupByte])
}
lockup.Add(lockup, block.Number(nodeCtx))

coinbaseAddr := tx.To().Bytes20()
Expand Down Expand Up @@ -815,7 +825,13 @@ func (c *ChainIndexer) addOutpointsToIndexer(addressOutpointsWithBlockHeight map
}
}
} else if tx.EtxType() == types.ConversionType && tx.To().IsInQiLedgerScope() {
lock := new(big.Int).Add(block.Number(nodeCtx), new(big.Int).SetUint64(params.ConversionLockPeriod))
var lockup *big.Int
if block.NumberU64(common.ZONE_CTX) < params.GoldenAgeForkNumberV1 {
lockup = new(big.Int).SetUint64(params.OldConversionLockPeriod)
} else {
lockup = new(big.Int).SetUint64(params.NewConversionLockPeriod)
}
lock := new(big.Int).Add(block.Number(nodeCtx), lockup)
value := tx.Value()
addr20 := tx.To().Bytes20()
binary.BigEndian.PutUint32(addr20[16:], uint32(block.NumberU64(nodeCtx)))
Expand Down
4 changes: 4 additions & 0 deletions core/core.go
Original file line number Diff line number Diff line change
Expand Up @@ -1044,6 +1044,10 @@ func (c *Core) GetMinerEndpoints() []string {
return c.endpoints
}

func (c *Core) CalcMaxBaseFee(block *types.WorkObject) (*big.Int, error) {
return c.sl.hc.CalcMaxBaseFee(block)
}

//--------------------//
// BlockChain methods //
//--------------------//
Expand Down
19 changes: 19 additions & 0 deletions core/evm.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
"github.com/dominant-strategies/go-quai/core/types"
"github.com/dominant-strategies/go-quai/core/vm"
"github.com/dominant-strategies/go-quai/log"
"github.com/dominant-strategies/go-quai/params"
)

// ChainContext supports retrieving headers and consensus parameters from the
Expand Down Expand Up @@ -54,7 +55,10 @@ type ChainContext interface {
CheckIfEtxIsEligible(common.Hash, common.Location) bool

CheckInCalcOrderCache(common.Hash) (*big.Int, int, bool)

AddToCalcOrderCache(common.Hash, int, *big.Int)

CalcMaxBaseFee(block *types.WorkObject) (*big.Int, error)
}

// NewEVMBlockContext creates a new context for use in the EVM.
Expand Down Expand Up @@ -102,6 +106,20 @@ func NewEVMBlockContext(header *types.WorkObject, parent *types.WorkObject, chai
}
}
etxEligibleSlices := primeTerminusHeader.EtxEligibleSlices()
maxBaseFee, err := chain.CalcMaxBaseFee(parent)
if maxBaseFee == nil && !chain.IsGenesisHash(parent.Hash()) {
return vm.BlockContext{}, fmt.Errorf("could not calculate max base fee %s", err)
}
if maxBaseFee == nil {
maxBaseFee = big.NewInt(0)
}

var averageBaseFee *big.Int
if header.NumberU64(common.ZONE_CTX) < params.GoldenAgeForkNumberV1 {
averageBaseFee = new(big.Int).Set(baseFee)
} else {
averageBaseFee = new(big.Int).Div(maxBaseFee, params.BaseFeeMultiplier)
}

return vm.BlockContext{
CanTransfer: CanTransfer,
Expand All @@ -116,6 +134,7 @@ func NewEVMBlockContext(header *types.WorkObject, parent *types.WorkObject, chai
CheckIfEtxEligible: chain.CheckIfEtxIsEligible,
EtxEligibleSlices: etxEligibleSlices,
QuaiStateSize: parent.QuaiStateSize(), // using the state size at the parent for all the gas calculations
AverageBaseFee: averageBaseFee,
}, nil
}

Expand Down
91 changes: 75 additions & 16 deletions core/state_processor.go
Original file line number Diff line number Diff line change
Expand Up @@ -455,9 +455,19 @@ func (p *StateProcessor) Process(block *types.WorkObject, batch ethdb.Batch) (ty
if int(lockupByte) > len(params.LockupByteToBlockDepth)-1 {
return nil, nil, nil, nil, 0, 0, 0, nil, nil, fmt.Errorf("coinbase lockup byte %d is out of range", lockupByte)
}
lockup := new(big.Int).SetUint64(params.LockupByteToBlockDepth[lockupByte])
if lockup.Uint64() < params.ConversionLockPeriod {
return nil, nil, nil, nil, 0, 0, 0, nil, nil, fmt.Errorf("coinbase lockup period is less than the minimum lockup period of %d blocks", params.ConversionLockPeriod)
var lockup *big.Int
// The first lock up period changes after the fork
if lockupByte == 0 {
if block.NumberU64(common.ZONE_CTX) < params.GoldenAgeForkNumberV1 {
lockup = new(big.Int).SetUint64(params.OldConversionLockPeriod)
} else {
lockup = new(big.Int).SetUint64(params.NewConversionLockPeriod)
}
} else {
lockup = new(big.Int).SetUint64(params.LockupByteToBlockDepth[lockupByte])
if lockup.Uint64() < params.OldConversionLockPeriod {
return nil, nil, nil, nil, 0, 0, 0, nil, nil, fmt.Errorf("coinbase lockup period is less than the minimum lockup period of %d blocks", params.OldConversionLockPeriod)
}
}
lockup.Add(lockup, blockNumber)
value := params.CalculateCoinbaseValueWithLockup(tx.Value(), lockupByte)
Expand Down Expand Up @@ -500,7 +510,13 @@ func (p *StateProcessor) Process(block *types.WorkObject, batch ethdb.Batch) (ty
}
if etx.To().IsInQiLedgerScope() {
if etx.ETXSender().Location().Equal(*etx.To().Location()) { // Quai->Qi Conversion
lock := new(big.Int).Add(header.Number(nodeCtx), new(big.Int).SetUint64(params.ConversionLockPeriod))
var lockup *big.Int
if block.NumberU64(common.ZONE_CTX) < params.GoldenAgeForkNumberV1 {
lockup = new(big.Int).SetUint64(params.OldConversionLockPeriod)
} else {
lockup = new(big.Int).SetUint64(params.NewConversionLockPeriod)
}
lock := new(big.Int).Add(block.Number(nodeCtx), lockup)
value := etx.Value()
txGas := etx.Gas()
if txGas < params.TxGas {
Expand Down Expand Up @@ -538,7 +554,7 @@ func (p *StateProcessor) Process(block *types.WorkObject, batch ethdb.Batch) (ty
}
utxosCreatedDeleted.UtxosCreatedHashes = append(utxosCreatedDeleted.UtxosCreatedHashes, types.UTXOHash(etx.Hash(), outputIndex, utxo))
utxosCreatedDeleted.UtxosCreatedKeys = append(utxosCreatedDeleted.UtxosCreatedKeys, rawdb.UtxoKeyWithDenomination(etx.Hash(), outputIndex, utxo.Denomination))
p.logger.Infof("Converting Quai to Qi %032x with denomination %d index %d lock %d\n", tx.Hash(), denomination, outputIndex, lock)
p.logger.Debugf("Converting Quai to Qi %032x with denomination %d index %d lock %d\n", tx.Hash(), denomination, outputIndex, lock)
outputIndex++
}
}
Expand Down Expand Up @@ -815,20 +831,47 @@ func (p *StateProcessor) Process(block *types.WorkObject, batch ethdb.Batch) (ty
// This function is intended to be run as part of the block processing.
// Returns the list of unlocked coinbases
func RedeemLockedQuai(hc *HeaderChain, header *types.WorkObject, parent *types.WorkObject, statedb *state.StateDB) (error, []common.Unlock) {
// Array of specific block depths for which we will redeem the Quai
blockDepths := []uint64{
params.ConversionLockPeriod,
params.LockupByteToBlockDepth[0],
params.LockupByteToBlockDepth[1],
params.LockupByteToBlockDepth[2],
params.LockupByteToBlockDepth[3],
currentBlockHeight := header.Number(hc.NodeCtx()).Uint64()

var blockDepths []uint64
if currentBlockHeight < params.GoldenAgeForkNumberV1 {
blockDepths = []uint64{
params.OldConversionLockPeriod,
params.LockupByteToBlockDepth[0],
params.LockupByteToBlockDepth[1],
params.LockupByteToBlockDepth[2],
params.LockupByteToBlockDepth[3],
}
} else {
blockDepths = []uint64{
params.LockupByteToBlockDepth[0],
params.LockupByteToBlockDepth[1],
params.LockupByteToBlockDepth[2],
params.LockupByteToBlockDepth[3],
}
}
// Array of specific block depths for which we will redeem the Quai

currentBlockHeight := header.Number(hc.NodeCtx()).Uint64()
unlocks := []common.Unlock{}

// Loop through the predefined block depths
for _, blockDepth := range blockDepths {
for i, blockDepth := range blockDepths {

// Minimum lock period is neutered between the fork number + old
// conversion period and fork number + new conversion period
if i == 0 {
if currentBlockHeight >= params.GoldenAgeForkNumberV1+params.OldConversionLockPeriod &&
currentBlockHeight < params.GoldenAgeForkNumberV1+params.NewConversionLockPeriod {
continue
}

if currentBlockHeight >= params.GoldenAgeForkNumberV1+params.NewConversionLockPeriod {
// block depth for the first index gets changed into the new conversion lock period
// after the fork height + new conversion number
blockDepth = params.NewConversionLockPeriod
}
}

// Ensure we can look back far enough
if currentBlockHeight <= blockDepth {
// Skip this depth if the current block height is less than or equal to the block depth
Expand All @@ -854,7 +897,16 @@ func RedeemLockedQuai(hc *HeaderChain, header *types.WorkObject, parent *types.W
}

lockupByte := etx.Data()[0]
lockup := params.LockupByteToBlockDepth[lockupByte]
// if lock up byte is 0, the fork change updates the lockup time
var lockup uint64
if lockupByte == 0 {
lockup = params.OldConversionLockPeriod
if currentBlockHeight >= params.GoldenAgeForkNumberV1+params.NewConversionLockPeriod {
lockup = params.NewConversionLockPeriod
}
} else {
lockup = params.LockupByteToBlockDepth[lockupByte]
}
if lockup == blockDepth {
balance := params.CalculateCoinbaseValueWithLockup(etx.Value(), lockupByte)

Expand All @@ -879,7 +931,14 @@ func RedeemLockedQuai(hc *HeaderChain, header *types.WorkObject, parent *types.W
}
}

if types.IsConversionTx(etx) && etx.To().IsInQuaiLedgerScope() && blockDepth == params.ConversionLockPeriod {
var conversionPeriodValid bool
if currentBlockHeight < params.GoldenAgeForkNumberV1 {
conversionPeriodValid = blockDepth == params.OldConversionLockPeriod
} else {
conversionPeriodValid = blockDepth == params.NewConversionLockPeriod
}

if types.IsConversionTx(etx) && etx.To().IsInQuaiLedgerScope() && conversionPeriodValid {
internal, err := etx.To().InternalAddress()
if err != nil {
fmt.Errorf("Error converting address to internal address: %v", err)
Expand Down
2 changes: 1 addition & 1 deletion core/state_transition.go
Original file line number Diff line number Diff line change
Expand Up @@ -364,7 +364,7 @@ func (st *StateTransition) TransitionDb() (*ExecutionResult, error) {
}
balance := st.evm.StateDB.GetBalance(fromInternal)
st.evm.StateDB.Suicide(fromInternal)
refund := new(big.Int).Mul(st.evm.Context.BaseFee, new(big.Int).SetUint64(params.CallNewAccountGas(st.evm.Context.QuaiStateSize)))
refund := new(big.Int).Mul(st.evm.Context.AverageBaseFee, new(big.Int).SetUint64(params.CallNewAccountGas(st.evm.Context.QuaiStateSize)))
balance.Add(balance, refund)
st.evm.StateDB.AddBalance(beneficiary, balance)

Expand Down
1 change: 1 addition & 0 deletions core/tx_pool.go
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@ type blockChain interface {
CheckInCalcOrderCache(common.Hash) (*big.Int, int, bool)
AddToCalcOrderCache(common.Hash, int, *big.Int)
CalcMinBaseFee(block *types.WorkObject) *big.Int
CalcMaxBaseFee(block *types.WorkObject) (*big.Int, error)
}

// TxPoolConfig are the configuration parameters of the transaction pool.
Expand Down
1 change: 1 addition & 0 deletions core/vm/evm.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ type BlockContext struct {
Time *big.Int // Provides information for TIME
Difficulty *big.Int // Provides information for DIFFICULTY
BaseFee *big.Int // Provides information for BASEFEE
AverageBaseFee *big.Int // Average base fee for the last 100 blocks
QuaiStateSize *big.Int // Provides information for QUAISTATESIZE

// Prime Terminus information for the given block
Expand Down
2 changes: 1 addition & 1 deletion core/vm/instructions.go
Original file line number Diff line number Diff line change
Expand Up @@ -867,7 +867,7 @@ func opSuicide(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]
}
balance := interpreter.evm.StateDB.GetBalance(addr)
interpreter.evm.StateDB.AddBalance(beneficiaryAddr, balance)
refund := new(big.Int).Mul(interpreter.evm.Context.BaseFee, new(big.Int).SetUint64(params.CallNewAccountGas(interpreter.evm.Context.QuaiStateSize)))
refund := new(big.Int).Mul(interpreter.evm.Context.AverageBaseFee, new(big.Int).SetUint64(params.CallNewAccountGas(interpreter.evm.Context.QuaiStateSize)))
interpreter.evm.StateDB.AddBalance(beneficiaryAddr, refund)
interpreter.evm.StateDB.Suicide(addr)
return nil, nil
Expand Down
29 changes: 24 additions & 5 deletions core/worker.go
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,7 @@ func newWorker(config *Config, chainConfig *params.ChainConfig, db ethdb.Databas
uncles, _ := lru.New[common.Hash, types.WorkObjectHeader](c_uncleCacheSize)
worker.uncles = uncles
// Set the GasFloor of the worker to the minGasLimit
worker.config.GasFloor = params.MinGasLimit
worker.config.GasFloor = params.MinGasLimit(headerchain.CurrentHeader().NumberU64(common.ZONE_CTX))

phBodyCache, _ := lru.New[common.Hash, types.WorkObject](pendingBlockBodyLimit)
worker.pendingBlockBody = phBodyCache
Expand Down Expand Up @@ -1093,9 +1093,22 @@ func (w *worker) commitTransaction(env *environment, parent *types.WorkObject, t
}
}
if tx.To().IsInQiLedgerScope() {
lockup := new(big.Int).SetUint64(params.LockupByteToBlockDepth[lockupByte])
if lockup.Uint64() < params.ConversionLockPeriod {
return nil, false, fmt.Errorf("coinbase lockup period is less than the minimum lockup period of %d blocks", params.ConversionLockPeriod)
var lockup *big.Int
// The first lock up period changes after the fork
if lockupByte == 0 {
if env.wo.NumberU64(common.ZONE_CTX) < params.GoldenAgeForkNumberV1 {
lockup = new(big.Int).SetUint64(params.OldConversionLockPeriod)
if lockup.Uint64() < params.OldConversionLockPeriod {
return nil, false, fmt.Errorf("coinbase lockup period is less than the minimum lockup period of %d blocks", params.OldConversionLockPeriod)
}
} else {
lockup = new(big.Int).SetUint64(params.NewConversionLockPeriod)
if lockup.Uint64() < params.NewConversionLockPeriod {
return nil, false, fmt.Errorf("coinbase lockup period is less than the minimum lockup period of %d blocks", params.NewConversionLockPeriod)
}
}
} else {
lockup = new(big.Int).SetUint64(params.LockupByteToBlockDepth[lockupByte])
}
lockup.Add(lockup, env.wo.Number(w.hc.NodeCtx()))
value := params.CalculateCoinbaseValueWithLockup(tx.Value(), lockupByte)
Expand Down Expand Up @@ -1133,7 +1146,13 @@ func (w *worker) commitTransaction(env *environment, parent *types.WorkObject, t
gasUsed := env.wo.GasUsed()
if tx.ETXSender().Location().Equal(*tx.To().Location()) { // Quai->Qi conversion
txGas := tx.Gas()
lock := new(big.Int).Add(env.wo.Number(w.hc.NodeCtx()), new(big.Int).SetUint64(params.ConversionLockPeriod))
var lockup *big.Int
if env.wo.NumberU64(common.ZONE_CTX) < params.GoldenAgeForkNumberV1 {
lockup = new(big.Int).SetUint64(params.OldConversionLockPeriod)
} else {
lockup = new(big.Int).SetUint64(params.NewConversionLockPeriod)
}
lock := new(big.Int).Add(env.wo.Number(w.hc.NodeCtx()), lockup)
if env.parentOrder == nil {
return nil, false, errors.New("parent order not set")
}
Expand Down
2 changes: 1 addition & 1 deletion p2p/protocol/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,5 @@ const (
//
// Note, in this example, peers below `quai/8.0.0` are not tolerated even
// during the grace period.
ProtocolGraceHeight uint64 = 0
ProtocolGraceHeight uint64 = 40000
)
Loading
Loading