diff --git a/protocol/config/consensus.go b/protocol/config/consensus.go index 6719f10f..9738545d 100644 --- a/protocol/config/consensus.go +++ b/protocol/config/consensus.go @@ -1,11 +1,15 @@ package config import ( + "encoding/json" "time" - + "os" + "path/filepath" "github.com/algorand/go-algorand-sdk/v2/protocol" ) +const ConfigurableConsensusProtocolsFilename = "consensus.json" + // ConsensusParams specifies settings that might vary based on the // particular version of the consensus protocol. type ConsensusParams struct { @@ -818,6 +822,56 @@ func (cp ConsensusProtocols) Merge(configurableConsensus ConsensusProtocols) Con return staticConsensus } + +// LoadConfigurableConsensusProtocols loads the configurable protocols from the data directory +func LoadConfigurableConsensusProtocols(dataDirectory string) error { + newConsensus, err := PreloadConfigurableConsensusProtocols(dataDirectory) + if err != nil { + return err + } + if newConsensus != nil { + SetConfigurableConsensusProtocols(newConsensus) + } + return nil +} + +// SetConfigurableConsensusProtocols sets the configurable protocols. +func SetConfigurableConsensusProtocols(newConsensus ConsensusProtocols) ConsensusProtocols { + oldConsensus := Consensus + Consensus = newConsensus + // Set allocation limits + for _, p := range Consensus { + checkSetAllocBounds(p) + } + return oldConsensus +} + +// https://github.com/algorand/go-algorand/blob/21eec2d39b4ac93d66f9e930e7b07d45f8248c24/config/consensus.go#L787 +// PreloadConfigurableConsensusProtocols loads the configurable protocols from the data directory +// and merge it with a copy of the Consensus map. Then, it returns it to the caller. +func PreloadConfigurableConsensusProtocols(dataDirectory string) (ConsensusProtocols, error) { + consensusProtocolPath := filepath.Join(dataDirectory, ConfigurableConsensusProtocolsFilename) + file, err := os.Open(consensusProtocolPath) + + if err != nil { + if os.IsNotExist(err) { + // this file is not required, only optional. if it's missing, no harm is done. + return Consensus, nil + } + return nil, err + } + defer file.Close() + + configurableConsensus := make(ConsensusProtocols) + + decoder := json.NewDecoder(file) + err = decoder.Decode(&configurableConsensus) + if err != nil { + return nil, err + } + return Consensus.Merge(configurableConsensus), nil +} + // initConsensusProtocols defines the consensus protocol values and how values change across different versions of the protocol. // // These are the only valid and tested consensus values and transitions. Other settings are not tested and may lead to unexpected behavior.