Skip to content

Commit

Permalink
Merge pull request #5 from ChorusOne/include_fee_manager_contract
Browse files Browse the repository at this point in the history
Add fee rewards manager to possim
  • Loading branch information
enriquefynn authored Dec 21, 2023
2 parents 5f9a71f + 28835f2 commit 6682aeb
Show file tree
Hide file tree
Showing 5 changed files with 10,736 additions and 1 deletion.
9 changes: 9 additions & 0 deletions Tiltfile
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,15 @@ local_resource(
allow_parallel=True,
)

# Deploy fee manager library and main contract.
local_resource(
"deploy-fee-manager-contracts",
cmd="python3 -m eth_possim deploy-fee-manager-contracts",
deps=lh_beacon_nodes,
resource_deps=["deploy-deposit-contract"],
allow_parallel=True,
)

# Deploy validator nodes
for idx in range(cfg["cl"]["lh_node_count"]):
node_name = "val-lh-{}".format(idx)
Expand Down
53 changes: 52 additions & 1 deletion eth_possim/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from eth_possim.config import initialise_privatenet
from eth_possim.config.load import load_configuration
from eth_possim.config.patch import patch_cl_cfg
from eth_possim.contracts import deploy_contract_onchain
from eth_possim.contracts import deploy_contract_onchain, deploy_compiled_contract
from eth_possim.deposit import load_initial_deposit_tree
from eth_possim.utils import ensure_dir_exists

Expand Down Expand Up @@ -73,6 +73,57 @@ def deploy_batch_deposit_contract(rpc: str):
with open("./.data/configuration.yaml", "w") as f:
yaml.dump(cfg, f)

@cli.command()
@click.option("--rpc", help="RPC endpoint URL address.", default="")
def deploy_fee_manager_contracts(rpc: str):
"""Deploys the fee manager contracts: library and contract."""

with open("./.data/configuration.yaml", "r") as f:
cfg = yaml.safe_load(f)
if not rpc:
rpc = f"http://localhost:{cfg['haproxy']['el']['port_geth_rpc']}"

fee_manager_library_address = deploy_compiled_contract(
cfg=cfg,
rpc=rpc,
foundry_json_path=f"{cfg['resources']}/ethereum_compiled_contracts/CalculateAndSendRewards.json",
)

# Patch and write back `configuration.yaml`
cfg["cl"]["fee_manager_library_address"] = fee_manager_library_address

fee_manager_address = deploy_compiled_contract(
cfg=cfg,
rpc=rpc,
foundry_json_path=f"{cfg['resources']}/ethereum_compiled_contracts/FeeRewardsManager.json",
args=[2800],
libraries=[("__$c56d76a1417c078a963cba4fa22c45184c$__", fee_manager_library_address)]
)
cfg["cl"]["fee_manager_address"] = fee_manager_address

with open("./.data/configuration.yaml", "w") as f:
yaml.dump(cfg, f)

@cli.command()
@click.option("--rpc", help="RPC endpoint URL address.", default="")
@click.option("--path", help="Path to the contract source.")
@click.option("--cfg-key-address", help="Key in which to save the contract address.")
@click.option("--library", multiple=True, type=(str, str), help="Libraries to be replaced in the bytecode contract in the format key value")
@click.argument("args", nargs=-1)
def deploy_contract_bytecode(rpc: str, path: str, cfg_key_address: str, args: list, library: list):
"""Deploys a contract by the compiled bytecode and abi."""

with open("./.data/configuration.yaml", "r") as f:
cfg = yaml.safe_load(f)
if not rpc:
rpc = f"http://localhost:{cfg['haproxy']['el']['port_geth_rpc']}"

contract_address = deploy_compiled_contract(cfg=cfg, rpc=rpc, foundry_json_path=path, args=args, libraries=library)

# Patch and write back `configuration.yaml`
cfg["cl"][cfg_key_address] = contract_address
with open("./.data/configuration.yaml", "w") as f:
yaml.dump(cfg, f)

@cli.command()
@click.option("--rpc", help="RPC endpoint URL address.", default="")
Expand Down
46 changes: 46 additions & 0 deletions eth_possim/contracts.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,58 @@
import binascii
import json
import logging
import solcx
import web3
import re
from typing import List, Tuple


logger = logging.getLogger(__name__)

def deploy_compiled_contract(cfg: dict, rpc: str, foundry_json_path: str, args: list = [], libraries: List[Tuple[str, str]] = []) -> str:
with open(foundry_json_path, "r") as f:
foundry_json = json.loads(f.read())

bytecode_str = foundry_json["bytecode"]["object"][2:]
for library in libraries:
# Skip 0x from the library address.
bytecode_str = bytecode_str.replace(library[0], library[1][2:])
bytecode = binascii.unhexlify(bytecode_str)

abi = foundry_json["abi"]

w3 = web3.Web3(web3.Web3.HTTPProvider(rpc))
w3.middleware_onion.inject(
web3.middleware.geth_poa_middleware,
layer=0,
)

contract = w3.eth.contract(abi=abi, bytecode=bytecode)
account = w3.eth.account.from_key(cfg["el"]["funder"]["private_key"])
w3.eth.default_account = account
nonce = w3.eth.get_transaction_count(account.address)

deploy_tx = contract.constructor(*args).build_transaction(
{
"chainId": cfg["el"]["chain_id"],
# "gas": Let the function estimate gas.
# "gasPrice": Let the function estimate gas price.
"from": account.address,
"nonce": nonce,
}
)
signed_txn = w3.eth.account.sign_transaction(
deploy_tx,
private_key=cfg["el"]["funder"]["private_key"],
)
w3.eth.send_raw_transaction(signed_txn.rawTransaction)
tx_receipt = w3.eth.wait_for_transaction_receipt(signed_txn.hash)

logger.info(
f"Contract from '{foundry_json_path}' was published at address '{tx_receipt['contractAddress']}' [block: {tx_receipt['blockNumber']}]"
)

return tx_receipt["contractAddress"]

def deploy_contract_onchain(
cfg: dict, rpc: str, path: str, name: str, args: list = []
Expand Down
Loading

0 comments on commit 6682aeb

Please sign in to comment.