-
Notifications
You must be signed in to change notification settings - Fork 8
PR #69, #70: Chain Configurator Implementations
There is a change set which establishes chain configuration interface types https://github.com/etclabscore/multi-geth/pull/69, and an subsequent change set which installs these interfaces throughout multi-geth https://github.com/etclabscore/multi-geth/pull/70.
Go-Ethereum uses interfaces for a lot of important things.
-
type ChainReader interface
for Blockchain and Headerchains -
type Validator interface
for block validations. -
type Processor interface
for processing blocks. -
type Engine interface
for consensus engines -
etc.
-
https://github.com/etclabscore/multi-geth/blob/master/consensus/consensus.go#L32-L53
Interfaces are particularly useful when you want to emphasize a pattern of process, as opposed to a structure of data.
Go-Ethereum is very opinionated about it's structure of configuration data because it's very opinionated about the content of that data; it is designed and maintained in support of a few endorsed chain configurations.
Multi-Geth works to remove this opinion. As it has done so - refactoring to use EIP-driven feature implementation,
refactoring to expose legible and extensible Difficulty and Reward logics, and has done so all the while working to
retrofit a params.ChainConfig
data structure by simply adding fields and echoing a simple IsForked
pattern analogous to those fields.
As Multi-Geth grows it's cross-network relevance beyond the "canonical" chains, it also needs to grow it's awareness across clients. With the exception of Parity, its has been a general pattern for clients to be purpose built for a certain or limited set of chains. And Parity has been VERY popular, and has shown itself to be an indisposable tool for both development and production use across the EVM ecosystem. Multi-Geth wants to adopt this pattern, and bring this opinion-agnostic and highly-extensible, accessible attitude and resource to the Golang domain.
Implementing a Chain Configurator interface allows Multi-Geth to abstract the idea of chain configuration away from a noun and into a verb. It enables multi-geth to support various chain configuration data types natively, and to be able to act as leveragable intersection between them.
Want to convert between Parity and Go-Ethereum chain config JSON files?
convert.Convert(myParityConfig, myGethConfig)
Want to ask an abstract question comparing them? How about:
myParityConfig.GetEIP649Transition() == myGethConfig.GetEIP649Transition()
Even though these configuration schemas represent this idea very differently:
Parity:
blockReward: "2e+18",
difficultyBombDelay: {
0: 5000000
}
Geth:
ByzantiumBlock: 0
You can now interface with them in way that is reflective of, and congruent to, the IP specifications that initially shaped them. Beyond individual features, we can now also do some fancy things rather simply:
common.Forks(myGethConfig)
> [1150000 1920000 2150000 2500000 2650000 ...]
common.Identical(myGethConfig, myParityConfig)
> true
common.Valid(myGethConfig) && common.Valid(myParityConfig)
> true
And one of the nice things, behind the scenes, is that the methods available at the interface API level
use predicatable names and signatures, which means that the heavy-lifting logic for the methods above are largely dynamic,
implemented with the reflect
package. This reduces the space for developer maintenance and development cost, helps ensure
thoroughness and, well, configuration parity, and allows developers to reason in ways that value generalizeability and
communicable ecosystem-first patterns.
With this I hope to make a go-ethereum implementation that is a tool for the developers, instead of a tool from The Developers.
-
Resolve .gitmodules remote url. Either
- use etclabscore/tests,
- or multi-geth/tests permanently,
- or see if they'll take a PR upstream,
- or un-include the generated tests and remove the associated tooling and test runners.
-
Implement Aleth data type Configurator
-
Implement PyEthereum data type Configurator
-
Design and implement some global idea of Configuration default availability. This pattern (below) is not good. It should be some kind of iteration of a canonical set.
func dataDirPathForCtxChainConfig(ctx *cli.Context, baseDataDirPath string) string {
switch {
case ctx.GlobalBool(TestnetFlag.Name):
return filepath.Join(baseDataDirPath, "testnet")
case ctx.GlobalBool(ClassicFlag.Name):
return filepath.Join(baseDataDirPath, "classic")
case ctx.GlobalBool(MordorFlag.Name):
return filepath.Join(baseDataDirPath, "mordor")
case ctx.GlobalBool(SocialFlag.Name):
return filepath.Join(baseDataDirPath, "social")
case ctx.GlobalBool(MixFlag.Name):
return filepath.Join(baseDataDirPath, "mix")
case ctx.GlobalBool(EthersocialFlag.Name):
return filepath.Join(baseDataDirPath, "ethersocial")
case ctx.GlobalBool(MusicoinFlag.Name):
return filepath.Join(baseDataDirPath, "musicoin")
case ctx.GlobalBool(RinkebyFlag.Name):
return filepath.Join(baseDataDirPath, "rinkeby")
case ctx.GlobalBool(KottiFlag.Name):
return filepath.Join(baseDataDirPath, "kotti")
case ctx.GlobalBool(GoerliFlag.Name):
return filepath.Join(baseDataDirPath, "goerli")
}
return baseDataDirPath
}
- Implement an flag for passing a runtime Configurator value (ie read this JSON config file and run geth using it)
- Implement
echainspec
tool for working with chainspec values (conversion, validation, enumeration, identies) - Implement JSON files as canonical definitions for default chain configs