Skip to content

Commit

Permalink
Add fork section to genesis config, add validator and staking amount …
Browse files Browse the repository at this point in the history
…to update
  • Loading branch information
m-bo-one committed Sep 17, 2021
1 parent b461d27 commit dfb61e8
Show file tree
Hide file tree
Showing 12 changed files with 277 additions and 46 deletions.
52 changes: 48 additions & 4 deletions app/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (

"github.com/tendermint/tendermint/libs/kv"

"github.com/Oneledger/protocol/data/governance"
"github.com/Oneledger/protocol/data/network_delegation"
"github.com/Oneledger/protocol/external_apps/common"

Expand Down Expand Up @@ -95,8 +96,14 @@ func (app *App) chainInitializer() chainInitializer {
app.Context.govern.WithState(app.Context.deliver)
app.Context.btcTrackers.WithState(app.Context.deliver)

app.logger.Info("NexusBlock start at height: ", app.Context.cfg.Node.NexusBlock)
err := app.setupState(req.AppStateBytes)
forkMap, err := app.genesisDoc.ForkParams.ToMap()
if err != nil {
app.logger.Error("Failed to read fork map", "err", err)
return ResponseInitChain{}
}
utils.PrintStringMap(forkMap, "%s starts at height: %v\n", true)

err = app.setupState(req.AppStateBytes)
// This should cause consensus to halt
if err != nil {
app.logger.Error("Failed to setupState", "err", err)
Expand Down Expand Up @@ -133,14 +140,51 @@ func (app *App) commitVMChanges(req *abciTypes.RequestEndBlock) {
}
}

func (app *App) applyUpdate(req RequestBeginBlock) error {
height := req.Header.GetHeight()

if app.genesisDoc.ForkParams.IsFrankensteinBlock(height) {
govern := app.Context.govern

options, err := govern.GetStakingOptions()
if err != nil {
return err
}

options.TopValidatorCount = int64(32)
options.MinSelfDelegationAmount = *balance.NewAmountFromInt(1_000_000)

app.logger.Info("Updating top validator count to", options.TopValidatorCount)
app.logger.Info("Updating min self delegation amount to", options.MinSelfDelegationAmount)

err = govern.WithHeight(height).SetStakingOptions(*options)
if err != nil {
return errors.Wrap(err, "Setup Staking Options")
}
err = govern.WithHeight(height).SetLUH(governance.LAST_UPDATE_HEIGHT_STAKING)
if err != nil {
return errors.Wrap(err, "Unable to set last Update height")
}

app.logger.Info("Frankenstein applied at block", height)
}

return nil
}

func (app *App) blockBeginner() blockBeginner {
return func(req RequestBeginBlock) ResponseBeginBlock {
defer app.handlePanic()
gc := getGasCalculator(app.genesisDoc.ConsensusParams)
app.Context.deliver = storage.NewState(app.Context.chainstate).WithGas(gc)

// Apply update at specific height
if err := app.applyUpdate(req); err != nil {
panic(err)
}

// Update last block height and hash
if app.Context.cfg.IsNexusUpdate(req.Header.GetHeight()) {
if app.genesisDoc.ForkParams.IsFrankensteinUpdate(req.Header.GetHeight()) {
app.Context.stateDB.WithState(app.Context.deliver).SetHeightHash(uint64(req.Header.GetHeight()), ethcmn.BytesToHash(req.GetHash()))
}

Expand Down Expand Up @@ -346,7 +390,7 @@ func (app *App) blockEnder() blockEnder {
app.Context.validators.WithState(app.Context.deliver).ClearEvents()

// commit changes before the next execution
if app.Context.cfg.IsNexusUpdate(req.GetHeight()) {
if app.genesisDoc.ForkParams.IsFrankensteinUpdate(req.GetHeight()) {
app.commitVMChanges(&req)
}

Expand Down
8 changes: 8 additions & 0 deletions cmd/olfullnode/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ type genesisArgument struct {
totalFunds int64
initialTokenHolders []string

// fork
frankensteinBlock int64

ethUrl string
deploySmartcontracts bool
cloud bool
Expand Down Expand Up @@ -89,6 +92,8 @@ func init() {
genesisCmd.Flags().Int64Var(&genesisCmdArgs.totalFunds, "total_funds", 400000000, "The total amount of tokens in circulation")
genesisCmd.Flags().StringSliceVar(&genesisCmdArgs.initialTokenHolders, "initial_token_holders", []string{}, "Initial list of addresses that hold an equal share of Total funds")
genesisCmd.Flags().BoolVar(&genesisCmdArgs.deploySmartcontracts, "deploy_smart_contracts", false, "deploy eth contracts")
// fork
genesisCmd.Flags().Int64Var(&genesisCmdArgs.frankensteinBlock, "frankenstein_block", 1, "Fork block for frankenstein update")
}

func newMainetContext(args *genesisArgument) (*mainetContext, error) {
Expand Down Expand Up @@ -255,6 +260,9 @@ func runGenesis(_ *cobra.Command, _ []string) error {
return errors.Wrap(err, "failed to create new genesis file")
}
genesisDoc.Validators = validatorList
genesisDoc.ForkParams = &config.ForkParams{
FrankensteinBlock: genesisCmdArgs.frankensteinBlock,
}

for _, nodeName := range ctx.names {
nodeDir := filepath.Join(args.outputDir, nodeName)
Expand Down
2 changes: 1 addition & 1 deletion cmd/olfullnode/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ func init() {
}

type initContext struct {
genesis *consensus.GenesisDoc
genesis *config.GenesisDoc
logger *log.Logger
rootDir string
nodeName string
Expand Down
12 changes: 11 additions & 1 deletion cmd/olfullnode/save_state.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@ import (
"encoding/hex"
"encoding/json"
"fmt"
"github.com/Oneledger/protocol/data/network_delegation"
"io"
"os"
"path/filepath"
"strconv"
"strings"
"time"

"github.com/Oneledger/protocol/data/network_delegation"

"github.com/pkg/errors"
"github.com/spf13/cobra"
"github.com/tendermint/tendermint/types"
Expand Down Expand Up @@ -66,6 +68,10 @@ type publicKey struct {
Value []byte `json:"value"`
}

type ForkParams struct {
FrankensteinBlock string `json:"frankensteinBlock"`
}

type GenesisValidator struct {
Address string `json:"address"`
PubKey publicKey `json:"pub_key"`
Expand Down Expand Up @@ -332,6 +338,10 @@ func SaveChainState(application *app.App, filename string, directory string) err
_, err = fmt.Fprint(writer, token)
_, err = writer.Write([]byte("\n"))

writeStructWithTag(writer, ForkParams{
FrankensteinBlock: strconv.Itoa(int(genesisDoc.ForkParams.FrankensteinBlock)),
}, "fork")

for jsonDecoder.More() {
token, err = jsonDecoder.Token()

Expand Down
13 changes: 0 additions & 13 deletions config/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,6 @@ type Server struct {
rootDir string
}

func (cfg *Server) IsNexusUpdate(height int64) bool {
if cfg.Node == nil {
panic("Node config not set")
}
return cfg.Node.NexusBlock != 0 && cfg.Node.NexusBlock <= height
}

func (cfg *Server) RootDir() string {
return cfg.rootDir
}
Expand Down Expand Up @@ -198,9 +191,6 @@ type NodeConfig struct {
Auth Authorisation `toml:"Auth" desc:"the OwnerCredentials and RPCPrivateKey should be configured together"`

ChainStateRotation ChainStateRotationCfg `toml:"ChainStateRotation" desc:"the schedule for chain state rotation"`

// fork number
NexusBlock int64 `toml:"nexus_block" desc:"Start block number of nexus update"`
}

type Authorisation struct {
Expand Down Expand Up @@ -253,9 +243,6 @@ func DefaultNodeConfig() *NodeConfig {

//"btc" service temporarily disabled
Services: []string{"broadcast", "node", "owner", "query", "tx", "eth"},

// nexus fork
NexusBlock: 1_200_000,
}
}

Expand Down
150 changes: 149 additions & 1 deletion config/types.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,155 @@
package config

import (
"bytes"
"encoding/json"
"fmt"
"io/ioutil"
"time"

"github.com/pkg/errors"
tmbytes "github.com/tendermint/tendermint/libs/bytes"
tmos "github.com/tendermint/tendermint/libs/os"
tmtypes "github.com/tendermint/tendermint/types"
tmtime "github.com/tendermint/tendermint/types/time"
)

type GenesisDoc = tmtypes.GenesisDoc
type GenesisDoc struct {
GenesisTime time.Time `json:"genesis_time"`
ChainID string `json:"chain_id"`
ConsensusParams *tmtypes.ConsensusParams `json:"consensus_params,omitempty"`
Validators []tmtypes.GenesisValidator `json:"validators,omitempty"`
AppHash tmbytes.HexBytes `json:"app_hash"`
AppState json.RawMessage `json:"app_state,omitempty"`
ForkParams *ForkParams `json:"fork"`
}

// SaveAs is a utility method for saving GenensisDoc as a JSON file.
func (genDoc *GenesisDoc) SaveAs(file string) error {
genDocBytes, err := tmtypes.GetCodec().MarshalJSONIndent(genDoc, "", " ")
if err != nil {
return err
}
return tmos.WriteFile(file, genDocBytes, 0644)
}

// ValidatorHash returns the hash of the validator set contained in the GenesisDoc
func (genDoc *GenesisDoc) ValidatorHash() []byte {
vals := make([]*tmtypes.Validator, len(genDoc.Validators))
for i, v := range genDoc.Validators {
vals[i] = tmtypes.NewValidator(v.PubKey, v.Power)
}
vset := tmtypes.NewValidatorSet(vals)
return vset.Hash()
}

// ValidateAndComplete checks that all necessary fields are present
// and fills in defaults for optional fields left empty
func (genDoc *GenesisDoc) ValidateAndComplete() error {
if genDoc.ChainID == "" {
return errors.New("genesis doc must include non-empty chain_id")
}
if len(genDoc.ChainID) > tmtypes.MaxChainIDLen {
return errors.Errorf("chain_id in genesis doc is too long (max: %d)", tmtypes.MaxChainIDLen)
}

if genDoc.ConsensusParams == nil {
genDoc.ConsensusParams = tmtypes.DefaultConsensusParams()
} else if err := genDoc.ConsensusParams.Validate(); err != nil {
return err
}

if genDoc.ForkParams == nil {
genDoc.ForkParams = DefaultForkParams()
} else if err := genDoc.ForkParams.Validate(); err != nil {
return err
}

for i, v := range genDoc.Validators {
if v.Power == 0 {
return errors.Errorf("the genesis file cannot contain validators with no voting power: %v", v)
}
if len(v.Address) > 0 && !bytes.Equal(v.PubKey.Address(), v.Address) {
return errors.Errorf("incorrect address for validator %v in the genesis file, should be %v", v, v.PubKey.Address())
}
if len(v.Address) == 0 {
genDoc.Validators[i].Address = v.PubKey.Address()
}
}

if genDoc.GenesisTime.IsZero() {
genDoc.GenesisTime = tmtime.Now()
}

return nil
}

//------------------------------------------------------------
// Make genesis state from file

// GenesisDocFromJSON unmarshalls JSON data into a GenesisDoc.
func GenesisDocFromJSON(jsonBlob []byte) (*GenesisDoc, error) {
genDoc := GenesisDoc{}
err := tmtypes.GetCodec().UnmarshalJSON(jsonBlob, &genDoc)
if err != nil {
return nil, err
}

if err := genDoc.ValidateAndComplete(); err != nil {
return nil, err
}

return &genDoc, err
}

// GenesisDocFromFile reads JSON data from a file and unmarshalls it into a GenesisDoc.
func GenesisDocFromFile(genDocFile string) (*GenesisDoc, error) {
jsonBlob, err := ioutil.ReadFile(genDocFile)
if err != nil {
return nil, errors.Wrap(err, "Couldn't read GenesisDoc file")
}
genDoc, err := GenesisDocFromJSON(jsonBlob)
if err != nil {
return nil, errors.Wrap(err, fmt.Sprintf("Error reading GenesisDoc at %v", genDocFile))
}
return genDoc, nil
}

// ForkParams determine the fork blocks number where to apply the global update for network
type ForkParams struct {
FrankensteinBlock int64 `json:"frankensteinBlock"`
}

// DefaultForkParams initial config
func DefaultForkParams() *ForkParams {
return &ForkParams{
FrankensteinBlock: 1, // 0 means disabled as tendermint blocks started from 1
}
}

// ToMap converts fork struct to map
func (f *ForkParams) ToMap() (map[string]interface{}, error) {
var inMap map[string]interface{}
inrec, err := json.Marshal(f)
if err != nil {
return nil, err
}
err = json.Unmarshal(inrec, &inMap)
return inMap, err
}

// IsFrankensteinBlock check if fork update arrived to apply change at specific block
func (f *ForkParams) IsFrankensteinBlock(height int64) bool {
return f.FrankensteinBlock != 0 && f.FrankensteinBlock == height
}

// IsFrankensteinUpdate check if fork update arrived to apply changes after specific block
func (f *ForkParams) IsFrankensteinUpdate(height int64) bool {
return f.FrankensteinBlock != 0 && f.FrankensteinBlock <= height
}

// Validate validates the ForkParams to ensure all values are within their
// allowed limits, and returns an error if they are not.
func (f *ForkParams) Validate() error {
return nil
}
Loading

0 comments on commit dfb61e8

Please sign in to comment.