-
Notifications
You must be signed in to change notification settings - Fork 83
Refactoring of the chain packages #3062
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
Conversation
`pkg/chain/ethereum_v1` We need to make a transition towards the new chain package structure required for V2. Here is the first step.
This is no longer relevant for v2
5bac6d2 to
2dd5922
Compare
pdyraga
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is really good start. I would also consider moving:
pkg/chain/random-beaconpkg/chain/tbtc-v2pkg/chain/threshold-networkpkg/chain/ecdsa
under ethereum. But maybe in a separate PR to unblock the other work?
| @@ -1,104 +0,0 @@ | |||
| package cmd | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's add an issue to the last milestone to implement the relay command with a reference to this PR where we temporarily remove it.
This interface was an artificial bag for more specialized chain interfaces. The client code rarely needs all of them at once. In order to make things simpler, we decided to remove the `chain.Handle` interface and let the client code depend on specific chain interfaces.
# Conflicts: # pkg/chain/ethereum/ethereum.go
The v2 client should operate on the concept of the operator and staking provider. That said, the concept of staker is no longer needed. We take an opportunity and cleanup it here.
|
|
||
| func (esm *ethereumStakeMonitor) HasMinimumStake( | ||
| // TODO: Real implementation with v2 contracts. | ||
| func (sm *stakeMonitor) HasMinimumStake( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@tomaszslabon Your #3060 will need this function. The proposed approach is: the firewall package should define an interface it is expecting, or import chain.StakeMonitor. I think the latter is fine for the time being. Per #3010, we no longer want to check HasMinimumStake but HasStakeDelegation (we should rename this function). And the logic checking staking provider <> operator mapping and the TokenStaking roles should be checked inside HasStakeDelegated.
I think we should check both RandomBeacon and WalletRegistry for staking provider <> operator mapping. We want to have one network of nodes for both applications.
|
|
||
| // BlockCounter creates a BlockCounter that uses the block number in Ethereum. | ||
| func (c *Chain) BlockCounter() (chain.BlockCounter, error) { | ||
| return c.blockCounter, nil |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the idea behind this function? THe block counter comes from keep-common, right? Maybe this function should be a part of ethereum.go? 🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could put in ethereum.go but wanted to keep it in the same way as others generic features and align with how interfaces are declared in pkg/chain. Also, if we want to merge keep-common one day, the block counter will live here.
# Conflicts: # pkg/chain/chain.go
| func NewChain( | ||
| ctx context.Context, | ||
| config *ethereum.Config, | ||
| client ethutil.EthereumClient, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should probably be *ethclient.Client, from github.com/ethereum/go-ethereum/ethclient. We need (in the next PR, I am working on it) obtain ChainID with a call to chainID, err := client.ChainID(context.Background()) and this is not possible with ethutil.EthereumClient.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| config *ethereum.Config, | ||
| client ethutil.EthereumClient, | ||
| ) (*BeaconChain, error) { | ||
| chain, err := NewChain(ctx, config, client) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The problem with creating a new instance of the base chain in New* function of the application chain is that we will end up with multiple instances of the base chain: one for Random Beacon and one for TBTC. If the base chain holds the transaction mutex - and this feels like the right place - it means we have two mutexes.
To avoid it, I would consider keeping the base chain as a singleton and creating application chains using public functions of the base chain.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please also see fa75502 that deals with Connect function.
Current `golint` CI job raised a lot of errors in packages that will be removed soon. In the same time `golint` does not allow for ignoring those errors and became deprecated. We decided to remove it in favor of `gofmt` to maintain formatting rules. We will add a new linting tool soon.
pdyraga
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we modify our pre-commit hooks ?
| - name: Lint Go | ||
| uses: keep-network/golint-action@v1.0.2 | ||
| - name: Go format | ||
| uses: Jerome1337/gofmt-action@v1.0.4 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Non-blocking but we should fork in case this repository gets deleted one day.
Yeah! See 059ec4f |
Cleanup of the `pkg/beacon` package This pull request is the next step of the package refactoring started in #3062. It simplifies the structure of the `pkg/beacon` and makes some general cleanup. Specific changes are described below. Please review commit by commit to easily understand all changes. ### Remove the intermediary `relay` package So far, all the beacon code have lived under `pkg/beacon/relay/*`. The intermediary `relay` package turned out to be redundant and just made the package structure more complicated. This PR removes the `relay` package and places everything directly in the root `pkg/beacon` package. This makes sense because the core logic now lives there. ### Embed the `pkg/beacon/relay.go` file into the `pkg/beacon/node.go` file. There is a `Node` structure that encapsulates the behavior of the beacon node. So far, their code was scattered through two files `relay.go` and `node.go`. The rules behind that split were unclear so we decided to merge them together into a single `node.go` file that defines the `Node` type along with all their methods. ### Make the `Node` type package-private The aforementioned `Node` type is used internally by the `pkg/beacon` and should never be instantiated manually outside of the `pkg/beacon` package. External clients should use `beacon.Initialize` function. That said, we decided to make the `Node` type package-private. ### Adjustments around beacon chain interface So far, the beacon chain interface was living in the `pkg/beacon/relay/chain` package and was divided into two files `chain.go` and `result.go`. Since the `relay` package was removed, the new path is `pkg/beacon/chain` which is more straightforward. To adhere to this change, all code references that used `relaychain.Interface` are now using `beaconchain.Interface`. Also, the `result.go` file content was merged into the `chain.go` file, and all the nomenclature was adjusted to say about the "beacon chain interface" instead of the "relay chain". The interface was also aligned to be compatible with the new `pkg/chain/ethereum` package that we plan to use for v2. Ideally, the beacon chain interface should live directly in the `pkg/beacon` and should be named `beacon.Chain`. Unfortunately, that causes import cycles with the `dkg` and `entry` packages since `pkg/beacon` triggers the logic from there. Making that work would require a bigger refactoring that is described in the last section of this PR (see **Ideas for further refactoring**) ### Remove deprecated `StakerAddress` and replace it with `chain.Address` Since v2 doesn't use the concept of `staker`, the `StakerAddress` type was deprecated recently. Here we remove it and replace all occurrences with the new `chain.Address` type introduced recently. The `chain.Address` type represents a chain-agnostic address and is a good fit to replace the obsolete `StakerAddress`. ### Ideas for further refactoring As mentioned above, the best place for the beacon chain interface is the root `pkg/beacon`. However, that approach brings some import cycles. If we transform the `pkg/beacon/chain.Interface` to be `pkg/beacon.Chain`, the `pkg/beacon/dkg` and `pkg/beacon/entry` packages still need to import it. At the same time, the `node` type living in the `pkg/beacon` triggers the `pkg/beacon/dkg` and `pkg/beacon/entry` logic directly. To break the cycle, we need to make the root `pkg/beacon` independent of their sub-packages that hold the implementation of the DKG and entry signing logic. In order to do so, we would need to: - Move the `dkg.ThresholdSigner` to the `pkg/beacon` package and rename it to `beacon.Signer`. This type seems to belong to the core beacon logic and should not be tied to the specific DKG implementation provided by the `pkg/beacon/dkg` package - Decouple `pkg/beacon` from `pkg/beacon/dkg` and `pkg/beacon/entry` using the `beacon.DkgExecutor` and `beacon.RelayEntryExecutor` interfaces: ``` package beacon // Former `beaconchain.Interface` moved from `pkg/beacon/chain` type Chain interface { ... } // Former `dkg.ThresholdSigner` moved from `pkg/beacon/dkg` type Signer struct { ... } type DkgExecutor interface { Execute(chain Chain, channel net.BroadcastChannel, ...) (*Signer, error) } type RelayEntryExecutor interface { Execute(chain Chain, channel net.BroadcastChannel, signer *Signer, ...) error } ``` - Make `beacon.Intialize` accepting `beacon.DkgExecutor` and `beacon.RelayEntryExecutor` interfaces and use them to trigger DKG and relay entry from within `beacon.node`. Those interfaces would be implemented by `pkg/beacon/dkg` and `pkg/beacon/entry` respectively. Those implementation would be injected in the `cmd/start.go` file. Those changes will introduce a proper direction of dependencies in the entire `pkg/beacon` package and will allow to easily test the `pkg/beacon` code by providing DKG and entry stubs.
Depends on: #3034
This pull request refactors the chain package structure to match the expectations of v2. I recommend going commit by commit to grasp the changes in an easy way.
Planned packages structure for v2
We aim for the following structure of packages:
This structure allows each application package (
pkg/beaconandpkg/tbtc) to set and control their own expectations regarding the chain. Thepkg/chaincontains chain implementations that must implement application-specific chain interfaces. This way the chain implementation is decoupled from the application domain code and does not affect it. Chain-agnostic interfaces declared directly in thepkg/chainpackage represents cross-application chain concepts that are shared by all applications.Steps towards the desired structure done in this PR
This PR makes the following steps to reach the desired structure:
pkg/chain/ethereumpackage topkg/chain/ethereum_v1and adjusts all the referencespkg/chain/ethereumthat consists of the baseethereum.Chainchain handle placed inethereum.goand app-specific chain handlesethereum.BeaconChainandethereum.TbtcChainplaced inbeacon.goandtbtc.gorespectively.chain.Handleinterface that was living inpkg/chainin favor of small specialized interfaces scattered through separate files likestake_monitor.go,block_counter.goand so on.chain.Stakerthus the entire concept of staker as it no longer relevant for v2pkg/chain/ethereumpackage. Those are the block counter, the stake monitor and the signer.Next steps that need to be done
To completely transition towards the new structure we still need to:
pkg/chain/ethereumpkg/beaconstructure to havechain.goat the rootpkg/chain/ethereumto contain references to v2 contract bindings and all the required featurespkg/chain/ethereum_v1package in favor ofpkg/chain/ethereum.