package config import ( "encoding/base64" "fmt" "time" "git.marketally.com/tutus-one/tutus-chain/pkg/core/native/noderoles" "git.marketally.com/tutus-one/tutus-chain/pkg/crypto/keys" "gopkg.in/yaml.v3" ) // Genesis represents a set of genesis block settings including the extensions // enabled in the genesis block or during native contracts initialization. type Genesis struct { // MaxTraceableBlocks is the length of the chain tail accessible to smart // contracts. It differs from Protocol level configuration in that this // value is used starting from HFEchidna to initialize MaxTraceableBlocks // value of native Policy contract. MaxTraceableBlocks uint32 // MaxValidUntilBlockIncrement is the upper increment size of blockchain // height (in blocks) exceeding that a transaction should fail validation. // It differs from Protocol level configuration in that this value is used // starting from HFEchidna to initialize MaxValidUntilBlockIncrement value // of native Policy contract. MaxValidUntilBlockIncrement uint32 // Roles contains the set of roles that should be designated during native // Designation contract initialization. It is NeoGo extension and must be // disabled on the public Neo N3 networks. Roles map[noderoles.Role]keys.PublicKeys // TimePerBlock is the minimum time interval between blocks that consensus // nodes work with. It must be an integer number of milliseconds. It differs // from Protocol level configuration in that this value is used starting // from HFEchidna to initialize MillisecondsPerBlock value of native Policy // contract. TimePerBlock time.Duration // Transaction contains transaction script that should be deployed in the // genesis block. It is NeoGo extension and must be disabled on the public // Neo N3 networks. Transaction *GenesisTransaction } // GenesisTransaction is a placeholder for script that should be included into genesis // block as a transaction script with the given system fee. Provided // system fee value will be taken from the standby validators account which is // added to the list of Signers as a sender with CalledByEntry scope. type GenesisTransaction struct { Script []byte SystemFee int64 } type ( // genesisAux is an auxiliary structure for Genesis YAML marshalling. genesisAux struct { MaxTraceableBlocks uint32 `yaml:"MaxTraceableBlocks"` MaxValidUntilBlockIncrement uint32 `yaml:"MaxValidUntilBlockIncrement"` Roles map[string]keys.PublicKeys `yaml:"Roles"` TimePerBlock time.Duration `yaml:"TimePerBlock"` Transaction *genesisTransactionAux `yaml:"Transaction"` } // genesisTransactionAux is an auxiliary structure for GenesisTransaction YAML // marshalling. genesisTransactionAux struct { Script string `yaml:"Script"` SystemFee int64 `yaml:"SystemFee"` } ) // MarshalYAML implements the YAML marshaler interface. func (e Genesis) MarshalYAML() (any, error) { var aux genesisAux aux.Roles = make(map[string]keys.PublicKeys, len(e.Roles)) for r, ks := range e.Roles { aux.Roles[r.String()] = ks } if e.Transaction != nil { aux.Transaction = &genesisTransactionAux{ Script: base64.StdEncoding.EncodeToString(e.Transaction.Script), SystemFee: e.Transaction.SystemFee, } } aux.MaxValidUntilBlockIncrement = e.MaxValidUntilBlockIncrement aux.TimePerBlock = e.TimePerBlock aux.MaxTraceableBlocks = e.MaxTraceableBlocks return aux, nil } // UnmarshalYAML implements the YAML unmarshaler interface. func (e *Genesis) UnmarshalYAML(node *yaml.Node) error { var aux genesisAux if err := node.Decode(&aux); err != nil { return err } e.Roles = make(map[noderoles.Role]keys.PublicKeys) for s, ks := range aux.Roles { r, ok := noderoles.FromString(s) if !ok { return fmt.Errorf("unknown node role: %s", s) } e.Roles[r] = ks } if aux.Transaction != nil { script, err := base64.StdEncoding.DecodeString(aux.Transaction.Script) if err != nil { return fmt.Errorf("failed to decode script of genesis transaction: %w", err) } e.Transaction = &GenesisTransaction{ Script: script, SystemFee: aux.Transaction.SystemFee, } } e.MaxValidUntilBlockIncrement = aux.MaxValidUntilBlockIncrement e.TimePerBlock = aux.TimePerBlock e.MaxTraceableBlocks = aux.MaxTraceableBlocks return nil }