Due to our constrained CI resources available to us, this PR disables
`blockscout` from running in the CI.
This PR makes it so `minimal` runs don't use blockscout, and changes the
CI to use this instead of the verified network.
WARNING: This PR changes the kurtosis package to use the one from
upstream, not our fork, as it was not working at the moment. This should
be changed when fixed.
In this PR:
1. Turn `launch-kurtosis` script into a CLI, which parses parameters and
can interactively run multiple steps.
2. Separate steps of such CLI into their own scripts.
1. New script created `launch-kurtosis`, which detects if an enclave is
running and prompts to relaunch it if it is.
2. New script created `deploy-contracts` to deploy all contracts. It can
optionally verify them as well.
3. Each step can be interactively opted in/out, or choose whether to run
it via CLI params.
4. The CLI offers a help command as well.
5. Cleanup logs of CLI. Logs of internal commands ran can be printed
with LOG_LEVEL=debug. In case of error, they are always printed out.
This PR adds the basic framework for E2E and the greater typescript
testing framework for the repo.
### Contents
- CI workflow for running E2E tests on push to main, PRs and manual
- Test suite for E2E
- Currently only read-only tests
- Using `bun:test` for time being but we can always change in future
- We are using the logging library `pino` so we can help with debugging
- set environment variable `LOG_LEVEL` to get extra information on
helpers
- Local `utils` namespace for all our test suites for easy importing
- Has helpers which interact with both the docker driver and also
blockscout backend
- Allows us to fetch deployed smart contracts by their name or address
and interact with them
---------
Co-authored-by: Facundo Farall <37149322+ffarall@users.noreply.github.com>
Based on https://github.com/paritytech/polkadot-sdk/pull/5868.
Note: this (somehow) breaks the ability to run a local network with the
zombienet config. It seems that the config generated by Zombienet that
automatically set the balance of validators is leading to an issue
(because of the address type).
---------
Co-authored-by: Facundo Farall <37149322+ffarall@users.noreply.github.com>
This PR adds a script one-liner to spin up an ethereum network, with
attached explorers and deploys our `/contracts` folder into there.
---------
Co-authored-by: Facundo Farall <37149322+ffarall@users.noreply.github.com>
I noticed `cargo clippy` was failing in CI, I fixed it. I still think we
should tweak the lints.
For example, clippy complains at things like `1 * HOURS ` because it's
redundant to multiply by 1, buy maybe we want it explicitly that way, so
it's more evident it can be changed. In this PR I don't tweak the rule
but try to make clippy happy.
In this PR:
1. Implement deployment script for all contracts involved. This includes
1. EigenLayer core contracts.
2. Snowbridge contracts.
3. Our custom contracts to interact with both protocols.
4. Update README to document functionalities of `contracts` directory.
Future work:
1. Deployment of EigenLayer contracts should be conditional, as we
wouldn't deploy them in testnet or mainnet, but we would do it in an
internal stagenet.
5. Cleaning up unused smart contracts.
This PR:
1. Adds some missing functionalities to connect the Snowbridge contracts
to the RewardsRegistry contract, through an Agent.
2. Adds a test suite for this integration, with a happy and unhappy
path. The former being with a valid and honest update of rewards, which
then a validator uses to claim them. The latter with a malicious message
that tries to update the rewards root, but it's not allowed.
This PR adds an initial implementation for a rewards registry, which
will be the contract in charge of allowing DataHaven validators to claim
the rewards they earned for being validators in the previous epoch. The
logic behind it is as follows:
- Whenever an epoch finishes, the corresponding BEEFY block gets relayed
to Ethereum through Snowbridge. This BEEFY block contains, in its
`extra` field, the merkle root of the tree that contains as leafs all
the message commitments of the messages of corresponding block, one of
which is the rewards distribution message.
- The rewards distribution message commitment is the root of the merkle
tree where each leaf is a tuple of the operator ID and the obtained era
points in the finished epoch. In this case, the operator ID is the
corresponding validator's Ethereum address.
- When the rewards distribution message is received, Snowbridge
validates it using the aforementioned BEEFY block and then dispatches
it. The dispatch invokes the `callContract` function of the
`RewardsAgent` agent, with the corresponding parameters so that this
agent calls the `updateRewardsMerkleRoot` function of the
`RewardsRegistry` contract with the new rewards distribution message
commitment.
- After this root is updated, any validator/operator can submit a proof
that it is in a leaf of the merkle tree that produced that root, which
means it has pending rewards to claim, through the
`ServiceManagerBase`'s `claimOperatorRewards` function.
- Each operator set of the AVS can have an assigned `RewardsRegistry`
contract. Operator sets that do not have an assigned `RewardsRegistry`
contract won't be able to received rewards.
This PR also adds two separate unit-test suites: one for the added
functionality to the `ServiceManagerBase` contract and one specific to
the new `RewardsRegistry` contract.
> [!CAUTION]
The `RewardsAgent` agent is the only one allowed to update the rewards'
merkle root, which means if a malicious user could get access to it it
could set the pending rewards to be claimed to an arbitrary tree that
benefits it. Extreme caution must be taken in the Substrate side so only
validated messages are sent to the Ethereum side, as to not allow any
users to impersonate being this agent.
### TODO:
Ideally, we would use the `RewardsCoordinator` contract from the
EigenLayer core to distribute the rewards, but currently that adds a
huge overhead for Operators since they'd have to wait for EigenLayer's
SideCar to snapshot state and update the distribution root (which
happens once a day), generate a proof that they belong to the tree of
that distribution root, store it while waiting for the `activationDelay`
(currently a week) to pass, and just then they would be able to claim
their earned rewards.
---------
Co-authored-by: Facundo Farall <37149322+ffarall@users.noreply.github.com>
Current implementation was incorrect as `Babe::find_author` returns an
index, not the author's account.
Deferred the logic of looking up the author's account based on the index
to the `pallet_session::FindAccountFromAuthorIndex` function, and use
the existing conversion from `AccountId20` to `H160`.
This PR remove the unneeded action that install rustfmt as it is now
already available. It remove a step in the CI.
The action removed is `dtolnay/rust-toolchain@stable`
---------
Co-authored-by: Facundo Farall <37149322+ffarall@users.noreply.github.com>
This PR adds a new job at the end of the `DataHave Operator Rust Tests`
(`rust-tests.yml`) that checks:
- If the tests were skipped (no changes in the `operator/` directory),
it succeeds.
- If the tests run and succeeded, it succeeds.
- If the tests run and failed, it fails.
This is useful to set this job as required in our merging ruleset, and
account for cases where the tests are skipped.
This PR:
- Sets up the slasher infrastructure with the base functionality
required (in `ISlasher.sol`, `SlasherBase.sol` and
`SlasherBaseStorage.sol`) and adds the tests for it (in
`SlasherBase.t.sol`).
- Adds an implementation of a more complex slasher (in
`IVetoableSlasher.sol` and `VetoableSlasher.sol`) and tests for it (in
`VetoableSlasher.t.sol`).
- Modifies the `ServiceManagerBase` contract to use the new
`VetoableSlasher` contract to manage slashing.
- Updates mocks and tests to reflect the newly added functionality.
---------
Co-authored-by: Facundo Farall <37149322+ffarall@users.noreply.github.com>
This PR add a github action that check for reported vulnerabilities in
dependencies. It can be triggered by two ways :
* Change in Cargo.toml or Crago.lock
* Once a week
Because it checks dependencies of dependencies it should not be required
to pass a PR.
The pallet_author_inherent was used for finding the author of the
current block, used in pallet_evm, among others, but it was tightly
coupled to the Nimbus protocol. Luckily, Babe also provides a
find_author that we can use for the same purpose.
This PR:
- Sets up an interface for message passing from a Substrate chain to the
Ethereum.
- Adds a diagram for understanding how messages are validated.
Adds the `Substrate` node and runtime, as well as configuration and test
files, from https://github.com/Moonsong-Labs/flamingo to the `operator`
folder in DataHaven
* forge install: forge-std
v1.9.6
* chore: 🏗️ Add `forge-std` submodule
* chore: 🏗️ Setup foundry project for AVS contracts
* ci: 👷 Restrict push execution of CI to `main` branch
* ci: 💚 Put restriction to `main` branch in `push` not in `pull_request`