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

Make Servicechain tx fee hardfork #2018

Open
wants to merge 9 commits into
base: dev
Choose a base branch
from
3 changes: 3 additions & 0 deletions blockchain/state_transition.go
Original file line number Diff line number Diff line change
Expand Up @@ -380,6 +380,9 @@ func (st *StateTransition) TransitionDb() (*ExecutionResult, error) {
effectiveGasPrice := st.gasPrice
txFee := getBurnAmountMagma(new(big.Int).Mul(new(big.Int).SetUint64(st.gasUsed()), effectiveGasPrice))
st.state.AddBalance(st.evm.Context.Rewardbase, txFee)
} else if rules.IsServiceChainRewardFix {
effectiveGasPrice := msg.EffectiveGasPrice(nil)
st.state.AddBalance(st.evm.Context.Rewardbase, new(big.Int).Mul(new(big.Int).SetUint64(st.gasUsed()), effectiveGasPrice))
} else {
effectiveGasPrice := msg.EffectiveGasPrice(nil)
st.state.AddBalance(st.evm.Context.Coinbase, new(big.Int).Mul(new(big.Int).SetUint64(st.gasUsed()), effectiveGasPrice))
Expand Down
2 changes: 1 addition & 1 deletion blockchain/types/block.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ type Header struct {

// Added with Randao hardfork for KIP-114 RANDAO.
RandomReveal []byte `json:"randomReveal,omitempty" rlp:"optional"` // 96 byte BLS signature
MixHash []byte `json:"mixHash,omitempty" rlp:"optional"` // 32 byte RANDAO mix
MixHash []byte `json:"mixHash,omitempty" rlp:"optional"` // 32 byte RANDAO mix

// New header fields must be added at tail for backward compatibility.
}
Expand Down
4 changes: 4 additions & 0 deletions cmd/homi/setup/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ var HomiFlags = []cli.Flag{
altsrc.NewInt64Flag(cancunCompatibleBlockNumberFlag),
altsrc.NewInt64Flag(kip103CompatibleBlockNumberFlag),
altsrc.NewStringFlag(kip103ContractAddressFlag),
altsrc.NewInt64Flag(serviceChainRewardFixCompatibleBlockNumberFlag),
altsrc.NewInt64Flag(randaoCompatibleBlockNumberFlag),
altsrc.NewStringFlag(kip113ProxyAddressFlag),
altsrc.NewStringFlag(kip113LogicAddressFlag),
Expand Down Expand Up @@ -771,6 +772,9 @@ func Gen(ctx *cli.Context) error {
genesisJson.Config.Kip103CompatibleBlock = big.NewInt(ctx.Int64(kip103CompatibleBlockNumberFlag.Name))
genesisJson.Config.Kip103ContractAddress = common.HexToAddress(ctx.String(kip103ContractAddressFlag.Name))

// ServiceChainRewardFix hardfork is optional
genesisJson.Config.ServiceChainRewardFixCompatibleBlock = big.NewInt(ctx.Int64(serviceChainRewardFixCompatibleBlockNumberFlag.Name))

genesisJson.Config.RandaoCompatibleBlock = big.NewInt(ctx.Int64(randaoCompatibleBlockNumberFlag.Name))

genesisJsonBytes, _ = json.MarshalIndent(genesisJson, "", " ")
Expand Down
7 changes: 7 additions & 0 deletions cmd/homi/setup/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -507,6 +507,13 @@ var (
Aliases: []string{"genesis.hardfork.kip103-contract-address"},
}

serviceChainRewardFixCompatibleBlockNumberFlag = &cli.Int64Flag{
Name: "servicechainrewardfix-compatible-blocknumber",
Usage: "ServiceChainRewardFixCompatible blockNumber",
Value: 0,
Aliases: []string{"genesis.hardfork.servicechainrewardfix-compatible-blocknumber"},
}

randaoCompatibleBlockNumberFlag = &cli.Int64Flag{
Name: "randao-compatible-blocknumber",
Usage: "randaoCompatible blockNumber",
Expand Down
1 change: 1 addition & 0 deletions governance/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -422,6 +422,7 @@ func getChainConfig(governance Engine, num *rpc.BlockNumber) *params.ChainConfig
config.CancunCompatibleBlock = latestConfig.CancunCompatibleBlock
config.Kip103CompatibleBlock = latestConfig.Kip103CompatibleBlock
config.Kip103ContractAddress = latestConfig.Kip103ContractAddress
config.ServiceChainRewardFixCompatibleBlock = latestConfig.ServiceChainRewardFixCompatibleBlock
config.RandaoCompatibleBlock = latestConfig.RandaoCompatibleBlock

return config
Expand Down
53 changes: 35 additions & 18 deletions params/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,9 @@ type ChainConfig struct {
RandaoCompatibleBlock *big.Int `json:"randaoCompatibleBlock,omitempty"` // RandaoCompatible activate block (nil = no fork)
RandaoRegistry *RegistryConfig `json:"randaoRegistry,omitempty"` // Registry initial states

// ServiceChainRewardFix is an optional hardfork
ServiceChainRewardFixCompatibleBlock *big.Int `json:"serviceChainRewardFixCompatibleBlock,omitempty"` // ServiceChainRewardFixCompatible switch block (nil = no fork, 0 already on)

// Various consensus engines
Gxhash *GxhashConfig `json:"gxhash,omitempty"` // (deprecated) not supported engine
Clique *CliqueConfig `json:"clique,omitempty"`
Expand Down Expand Up @@ -400,6 +403,15 @@ func (c *ChainConfig) IsRandaoForkBlockParent(num *big.Int) bool {
return c.RandaoCompatibleBlock.Cmp(nextNum) == 0 // randao == num + 1
}

// IsServiceChainRewardFixForkEnabled returns whether num is either equal to the ServiceChainRewardFix block or greater.
func (c *ChainConfig) IsServiceChainRewardFixForkEnabled(num *big.Int) bool {
if c.ServiceChainRewardFixCompatibleBlock == nil || num == nil {
return false
}

return isForked(c.ServiceChainRewardFixCompatibleBlock, num)
}

// CheckCompatible checks whether scheduled fork transitions have been imported
// with a mismatching chain configuration.
func (c *ChainConfig) CheckCompatible(newcfg *ChainConfig, height uint64) *ConfigCompatError {
Expand Down Expand Up @@ -485,6 +497,9 @@ func (c *ChainConfig) checkCompatible(newcfg *ChainConfig, head *big.Int) *Confi
if isForkIncompatible(c.RandaoCompatibleBlock, newcfg.RandaoCompatibleBlock, head) {
return newCompatError("Randao Block", c.RandaoCompatibleBlock, newcfg.RandaoCompatibleBlock)
}
if isForkIncompatible(c.ServiceChainRewardFixCompatibleBlock, newcfg.ServiceChainRewardFixCompatibleBlock, head) {
return newCompatError("SerivceChainTxFee Block", c.ServiceChainRewardFixCompatibleBlock, newcfg.ServiceChainRewardFixCompatibleBlock)
}
return nil
}

Expand Down Expand Up @@ -597,15 +612,16 @@ func (err *ConfigCompatError) Error() string {
// Rules is a one time interface meaning that it shouldn't be used in between transition
// phases.
type Rules struct {
ChainID *big.Int
IsIstanbul bool
IsLondon bool
IsEthTxType bool
IsMagma bool
IsKore bool
IsShanghai bool
IsCancun bool
IsRandao bool
ChainID *big.Int
IsIstanbul bool
IsLondon bool
IsEthTxType bool
IsMagma bool
IsKore bool
IsShanghai bool
IsCancun bool
IsRandao bool
IsServiceChainRewardFix bool
}

// Rules ensures c's ChainID is not nil.
Expand All @@ -615,15 +631,16 @@ func (c *ChainConfig) Rules(num *big.Int) Rules {
chainID = new(big.Int)
}
return Rules{
ChainID: new(big.Int).Set(chainID),
IsIstanbul: c.IsIstanbulForkEnabled(num),
IsLondon: c.IsLondonForkEnabled(num),
IsEthTxType: c.IsEthTxTypeForkEnabled(num),
IsMagma: c.IsMagmaForkEnabled(num),
IsKore: c.IsKoreForkEnabled(num),
IsShanghai: c.IsShanghaiForkEnabled(num),
IsCancun: c.IsCancunForkEnabled(num),
IsRandao: c.IsRandaoForkEnabled(num),
ChainID: new(big.Int).Set(chainID),
IsIstanbul: c.IsIstanbulForkEnabled(num),
IsLondon: c.IsLondonForkEnabled(num),
IsEthTxType: c.IsEthTxTypeForkEnabled(num),
IsMagma: c.IsMagmaForkEnabled(num),
IsKore: c.IsKoreForkEnabled(num),
IsShanghai: c.IsShanghaiForkEnabled(num),
IsCancun: c.IsCancunForkEnabled(num),
IsRandao: c.IsRandaoForkEnabled(num),
IsServiceChainRewardFix: c.IsServiceChainRewardFixForkEnabled(num),
}
}

Expand Down
18 changes: 10 additions & 8 deletions reward/reward_distributor.go
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,11 @@ func GetBlockReward(header *types.Header, rules params.Rules, pset *params.GovPa
spec.Proposer = spec.Proposer.Add(spec.Proposer, txFeeRemained)
spec.TotalFee = spec.TotalFee.Add(spec.TotalFee, txFee)
incrementRewardsMap(spec.Rewards, header.Rewardbase, txFeeRemained)
} else if rules.IsServiceChainRewardFix {
txFee := GetTotalTxFee(header, rules, pset)
spec.Proposer = spec.Proposer.Add(spec.Proposer, txFee)
spec.TotalFee = spec.TotalFee.Add(spec.TotalFee, txFee)
incrementRewardsMap(spec.Rewards, header.Rewardbase, txFee)
} else {
txFee := GetTotalTxFee(header, rules, pset)
spec.Proposer = spec.Proposer.Add(spec.Proposer, txFee)
Expand Down Expand Up @@ -254,17 +259,14 @@ func CalcDeferredRewardSimple(header *types.Header, rules params.Rules, pset *pa

// If not DeferredTxFee, fees are already added to the proposer during TX execution.
// Therefore, there are no fees to distribute here at the end of block processing.
// However, before Kore, there was a bug that distributed tx fee regardless
// of `deferredTxFee` flag. See https://github.com/klaytn/klaytn/issues/1692.
// However, there was a bug causing the fees to be distributed again.
// See https://github.com/klaytn/klaytn/issues/1692.
// To maintain backward compatibility, we only fix the buggy logic after Magma
// and leave the buggy logic before Magma.
// However, the fees must be compensated to calculate actual rewards paid.

// bug-fixed logic after Magma
if !rc.deferredTxFee && rc.rules.IsMagma {
// However, if you wish to address only this issue instead, apply the ServiceChainRewardFixHardfork.
// Before the hardforks, tx fees must be compensated to calculate actual rewards paid.
if !rc.deferredTxFee && (rc.rules.IsMagma || rc.rules.IsServiceChainRewardFix) {
proposer := new(big.Int).Set(minted)
logger.Debug("CalcDeferredRewardSimple after Kore when deferredTxFee=false returns",
"proposer", proposer)
spec := NewRewardSpec()
spec.Minted = minted
spec.TotalFee = big.NewInt(0)
Expand Down