Skip to content

Commit

Permalink
First goldenage fork, increasing min gas limit for contract deployment
Browse files Browse the repository at this point in the history
  • Loading branch information
gameofpointers committed Oct 25, 2024
1 parent 198b880 commit 3be7932
Show file tree
Hide file tree
Showing 13 changed files with 182 additions and 37 deletions.
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

0 comments on commit 3be7932

Please sign in to comment.