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

Governance upgrade & coinbase fix #36

Merged
merged 15 commits into from
Sep 12, 2023
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
2 changes: 1 addition & 1 deletion Dockerfile.metadium
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ RUN DEBIAN_FRONTEND=noninteractive apt-get install -y tzdata
RUN DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends build-essential ca-certificates curl libjemalloc-dev liblz4-dev libsnappy-dev libzstd-dev libudev-dev git

# golang
RUN curl -sL -o /tmp/go.tar.gz https://dl.google.com/go/$(curl -sL https://golang.org/VERSION?m=text).linux-amd64.tar.gz && \
RUN curl -sL -o /tmp/go.tar.gz https://dl.google.com/go/$(curl -sL https://golang.org/VERSION?m=text | head -1).linux-amd64.tar.gz && \
pushd /usr/local/ && \
tar xfz /tmp/go.tar.gz && \
cd /usr/local/bin/ && \
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ test: all
test-short: all
$(GORUN) build/ci.go test -short

lint: metadium/governance_abi.go metadium/governance_legacy_abi ## Run linters.
lint: metadium/governance_abi.go metadium/governance_legacy_abi.go ## Run linters.
$(GORUN) build/ci.go lint

clean:
Expand Down
131 changes: 96 additions & 35 deletions metadium/admin.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
"github.com/ethereum/go-ethereum/cmd/utils"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/ethereum/go-ethereum/log"
Expand Down Expand Up @@ -285,27 +286,26 @@ func (ma *metaAdmin) getInt(ctx context.Context, contract *metclient.RemoteContr
}
}

// TODO: error handling
func (ma *metaAdmin) getRegGovEnvContracts(ctx context.Context, height *big.Int) (reg, gov, env, staking *metclient.RemoteContract, err error) {
func (ma *metaAdmin) getRegGovEnvContracts(ctx context.Context, height *big.Int) (reg, gov, env, staking *metclient.RemoteContract, legacy bool, err error) {
if ma.registry == nil {
err = metaminer.ErrNotInitialized
return
}
reg = &metclient.RemoteContract{
Cli: ma.cli,
Abi: ma.registry.Abi,
Abi: registryContract.Abi,
}
env = &metclient.RemoteContract{
Cli: ma.cli,
Abi: ma.envStorage.Abi,
Abi: envStorageImpContract.Abi,
}
gov = &metclient.RemoteContract{
Cli: ma.cli,
Abi: ma.gov.Abi,
Abi: govContract.Abi,
}
staking = &metclient.RemoteContract{
Cli: ma.cli,
Abi: ma.staking.Abi,
Abi: stakingContract.Abi,
}
if ma.registry.To != nil {
reg.To = ma.registry.To
Expand Down Expand Up @@ -343,6 +343,18 @@ func (ma *metaAdmin) getRegGovEnvContracts(ctx context.Context, height *big.Int)
staking.To = &common.Address{}
staking.To.SetBytes(addr.Bytes())

// check if governance is legacy, i.e. if it doesn't have getMaxPriorityFeePerGas
var fee *big.Int
if err2 := metclient.CallContract(ctx, env, "getMaxPriorityFeePerGas", nil, &fee, height); err2 == nil {
legacy = false
} else {
legacy = true
reg.Abi = registryLegacyContract.Abi
gov.Abi = govLegacyContract.Abi
env.Abi = envStorageImpLegacyContract.Abi
staking.Abi = stakingLegacyContract.Abi
}

return
}

Expand Down Expand Up @@ -463,7 +475,7 @@ func (ma *metaAdmin) getMetaNodes(ctx context.Context, block *big.Int) ([]*metaN

func (ma *metaAdmin) getRewardParams(ctx context.Context, height *big.Int) (*rewardParameters, error) {
rp := &rewardParameters{}
reg, gov, env, staking, err := ma.getRegGovEnvContracts(ctx, height)
reg, gov, env, staking, _, err := ma.getRegGovEnvContracts(ctx, height)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -627,7 +639,7 @@ func (ma *metaAdmin) getGovData(refresh bool) (data *govdata, err error) {
return
}
data.blockNum = block.Number.Int64()
if !refresh && data.blockNum <= ma.lastBlock {
if !refresh && !ma.isLegacyGovernance && data.blockNum <= ma.lastBlock {
return
}

Expand All @@ -647,7 +659,7 @@ func (ma *metaAdmin) getGovData(refresh bool) (data *govdata, err error) {
if err != nil {
return
}
if !refresh && ma.modifiedBlock == data.modifiedBlock {
if !refresh && !ma.isLegacyGovernance && ma.modifiedBlock == data.modifiedBlock {
return
}

Expand Down Expand Up @@ -754,7 +766,7 @@ func (ma *metaAdmin) update() error {
return err
} else if latest.Number.Int64() == ma.lastBlock {
return nil
} else if reg, gov, env, staking, err := ma.getRegGovEnvContracts(ctx, latest.Number); err != nil {
} else if reg, gov, env, staking, _, err := ma.getRegGovEnvContracts(ctx, latest.Number); err != nil {
return err
} else {
ma.registry, ma.gov, ma.envStorage, ma.staking = reg, gov, env, staking
Expand Down Expand Up @@ -786,11 +798,16 @@ func (ma *metaAdmin) update() error {
}

if data, err := ma.getGovData(false); err == nil {
if data.modifiedBlock != 0 && ma.modifiedBlock != data.modifiedBlock {
if ma.isLegacyGovernance || (data.modifiedBlock != 0 && ma.modifiedBlock != data.modifiedBlock) {
ma.lock.Lock()
defer ma.lock.Unlock()

ma.isLegacyGovernance = false
ma.registry.Abi = registryContract.Abi
ma.gov.Abi = govContract.Abi
ma.envStorage.Abi = envStorageImpContract.Abi
ma.staking.Abi = stakingContract.Abi

ma.modifiedBlock = data.modifiedBlock
ma.blockInterval = data.blockInterval
ma.blocksPer = data.blocksPer
Expand Down Expand Up @@ -892,7 +909,7 @@ func (ma *metaAdmin) update() error {
setGasCoinbase(data.gasPrice)
}
if data.blockNum != 0 {
ma.lastBlock = int64(data.blockNum)
ma.lastBlock = data.blockNum
}

} else {
Expand Down Expand Up @@ -964,7 +981,7 @@ func StartAdmin(stack *node.Node, datadir string) {
}
syncCheck()

time.Sleep(time.Duration(5 * time.Second))
time.Sleep(5 * time.Second)
}
}()
}
Expand Down Expand Up @@ -1221,7 +1238,8 @@ func (ma *metaAdmin) calculateRewards(num, blockReward, fees *big.Int, addBalanc
}

func calculateRewards(num, blockReward, fees *big.Int, addBalance func(common.Address, *big.Int)) (*common.Address, []byte, error) {
if admin.isLegacyGovernance {
parentNum := new(big.Int).Sub(num, common.Big1)
if _, _, _, _, legacy, _ := admin.getRegGovEnvContracts(context.Background(), parentNum); legacy {
return admin.calculateRewardsLegacy(num, blockReward, fees, addBalance)
}
return admin.calculateRewards(num, blockReward, fees, addBalance)
Expand All @@ -1232,6 +1250,36 @@ func verifyRewards(num *big.Int, rewards string) error {
//return admin.verifyRewards(num, rewards)
}

func getCoinbase(height *big.Int) (coinbase common.Address, err error) {
if admin == nil {
err = metaminer.ErrNotInitialized
return
}
prvKey := admin.stack.Server().PrivateKey
if admin.self != nil {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()

num := new(big.Int).Sub(height, common.Big1)
_, gov, _, _, _, err2 := admin.getRegGovEnvContracts(ctx, num)
if err2 != nil {
err = err2
return
}

nodeId := crypto.FromECDSAPub(&prvKey.PublicKey)[1:]
if addr, err2 := enodeExists(ctx, height, gov, nodeId); err2 != nil {
err = err2
return
} else {
coinbase = addr
}
} else if admin.nodeInfo != nil && admin.nodeInfo.ID == admin.bootNodeId {
coinbase = admin.bootAccount
}
return
}

func signBlock(height *big.Int, hash common.Hash, isPangyo bool) (coinbase common.Address, nodeId, sig []byte, err error) {
if admin == nil {
err = metaminer.ErrNotInitialized
Expand All @@ -1251,7 +1299,7 @@ func signBlock(height *big.Int, hash common.Hash, isPangyo bool) (coinbase commo
defer cancel()

num := new(big.Int).Sub(height, common.Big1)
_, gov, _, _, err2 := admin.getRegGovEnvContracts(ctx, num)
_, gov, _, _, _, err2 := admin.getRegGovEnvContracts(ctx, num)
if err2 != nil {
err = err2
return
Expand Down Expand Up @@ -1279,7 +1327,7 @@ func verifyBlockSig(height *big.Int, coinbase common.Address, nodeId []byte, has

// get nodeid from the coinbase
num := new(big.Int).Sub(height, common.Big1)
_, gov, _, _, err := admin.getRegGovEnvContracts(ctx, num)
_, gov, _, _, _, err := admin.getRegGovEnvContracts(ctx, num)
if err != nil {
return err == metaminer.ErrNotInitialized
} else if count, err := admin.getInt(ctx, gov, num, "getMemberLength"); err != nil || count == 0 {
Expand Down Expand Up @@ -1460,7 +1508,7 @@ func getBlockBuildParameters(height *big.Int) (blockInterval int64, maxBaseFee,
blockBuildParamsLock.Unlock()

// default values
blockInterval = 15
blockInterval = 2000
maxBaseFee = big.NewInt(0)
gasLimit = big.NewInt(0)
baseFeeMaxChangeRate = 0
Expand All @@ -1473,32 +1521,44 @@ func getBlockBuildParameters(height *big.Int) (blockInterval int64, maxBaseFee,
defer cancel()

var env, gov *metclient.RemoteContract
if _, gov, env, _, err = admin.getRegGovEnvContracts(ctx, height); err != nil {
var legacy bool
if _, gov, env, _, legacy, err = admin.getRegGovEnvContracts(ctx, height); err != nil {
err = metaminer.ErrNotInitialized
return
} else if count, err2 := admin.getInt(ctx, gov, height, "getMemberLength"); err2 != nil || count == 0 {
err = metaminer.ErrNotInitialized
return
}
var v *big.Int
if err = metclient.CallContract(ctx, env, "getBlockCreationTime", nil, &v, height); err != nil {
err = metaminer.ErrNotInitialized
return
}
blockInterval = v.Int64()

gasLimitAndBaseFee := make([]*big.Int, 3)
if err = metclient.CallContract(ctx, env, "getGasLimitAndBaseFee", nil, &gasLimitAndBaseFee, height); err != nil {
err = metaminer.ErrNotInitialized
return
}
gasLimit = gasLimitAndBaseFee[0]
baseFeeMaxChangeRate = gasLimitAndBaseFee[1].Int64()
gasTargetPercentage = gasLimitAndBaseFee[2].Int64()
if legacy {
var header *types.Header
if header, err = admin.cli.HeaderByNumber(ctx, height); err != nil {
return
}
// for legacy governance use default values
blockInterval = 2000
gasLimit = new(big.Int).SetUint64(header.GasLimit)
} else {
var v *big.Int
if err = metclient.CallContract(ctx, env, "getBlockCreationTime", nil, &v, height); err != nil {
err = metaminer.ErrNotInitialized
return
}
blockInterval = v.Int64()

if err = metclient.CallContract(ctx, env, "getMaxBaseFee", nil, &maxBaseFee, height); err != nil {
err = metaminer.ErrNotInitialized
return
gasLimitAndBaseFee := make([]*big.Int, 3)
if err = metclient.CallContract(ctx, env, "getGasLimitAndBaseFee", nil, &gasLimitAndBaseFee, height); err != nil {
err = metaminer.ErrNotInitialized
return
}
gasLimit = gasLimitAndBaseFee[0]
baseFeeMaxChangeRate = gasLimitAndBaseFee[1].Int64()
gasTargetPercentage = gasLimitAndBaseFee[2].Int64()

if err = metclient.CallContract(ctx, env, "getMaxBaseFee", nil, &maxBaseFee, height); err != nil {
err = metaminer.ErrNotInitialized
return
}
}

// cache it
Expand Down Expand Up @@ -1865,6 +1925,7 @@ func init() {
metaminer.SuggestGasPriceFunc = suggestGasPrice
metaminer.CalculateRewardsFunc = calculateRewards
metaminer.VerifyRewardsFunc = verifyRewards
metaminer.GetCoinbaseFunc = getCoinbase
metaminer.SignBlockFunc = signBlock
metaminer.VerifyBlockSigFunc = verifyBlockSig
metaminer.RequirePendingTxsFunc = requirePendingTxs
Expand Down
Loading