"""Reinitialise a strategy state.
"""
import os
import shutil
from pathlib import Path
from typing import Optional
from eth_defi.hotwallet import HotWallet
from .app import app
from ..bootstrap import prepare_executor_id, create_web3_config, create_sync_model, create_state_store
from ..log import setup_logging
from ...ethereum.enzyme.vault import EnzymeVaultSyncModel
from ...strategy.execution_model import AssetManagementMode
from . import shared_options
[docs]@app.command()
def reinit(
id: str = shared_options.id,
name: str = shared_options.name,
strategy_file: Path = shared_options.strategy_file,
state_file: Optional[Path] = shared_options.state_file,
private_key: Optional[str] = shared_options.private_key,
log_level: str = shared_options.log_level,
asset_management_mode: AssetManagementMode = shared_options.asset_management_mode,
vault_address: Optional[str] = shared_options.vault_address,
vault_deployment_block_number: Optional[int] = shared_options.vault_deployment_block_number,
json_rpc_binance: Optional[str] = shared_options.json_rpc_binance,
json_rpc_polygon: Optional[str] = shared_options.json_rpc_polygon,
json_rpc_avalanche: Optional[str] = shared_options.json_rpc_avalanche,
json_rpc_ethereum: Optional[str] = shared_options.json_rpc_ethereum,
json_rpc_arbitrum: Optional[str] = shared_options.json_rpc_arbitrum,
json_rpc_anvil: Optional[str] = shared_options.json_rpc_anvil,
):
"""Reinitialise a strategy state.
Deletes all the state history of a state and starts tracking the strategy again.
This command will start the internal ledger accounting from the scratch.
All strategy live execution history is lost.
"""
global logger
id = prepare_executor_id(id, strategy_file)
logger = setup_logging(log_level)
web3config = create_web3_config(
gas_price_method=None,
json_rpc_binance=json_rpc_binance,
json_rpc_polygon=json_rpc_polygon,
json_rpc_avalanche=json_rpc_avalanche,
json_rpc_ethereum=json_rpc_ethereum,
json_rpc_arbitrum=json_rpc_arbitrum,
json_rpc_anvil=json_rpc_anvil,
)
assert web3config, "No RPC endpoints given. A working JSON-RPC connection is needed for check-wallet"
# Check that we are connected to the chain strategy assumes
web3config.choose_single_chain()
if private_key is not None:
hot_wallet = HotWallet.from_private_key(private_key)
else:
hot_wallet = None
web3 = web3config.get_default()
sync_model = create_sync_model(
asset_management_mode,
web3,
hot_wallet,
vault_address,
)
logger.info("RPC details")
# Check the chain is online
logger.info(f" Chain id is {web3.eth.chain_id:,}")
logger.info(f" Latest block is {web3.eth.block_number:,}")
# Check balances
logger.info("Balance details")
logger.info(" Hot wallet is %s", hot_wallet.address)
vault_address = sync_model.get_vault_address()
start_block = None
if vault_address:
logger.info(" Vault is %s", vault_address)
if vault_deployment_block_number:
start_block = vault_deployment_block_number
logger.info(" Vault deployment block number is %d", start_block)
if not state_file:
state_file = f"state/{id}.json"
state_file = Path(state_file)
store = create_state_store(state_file)
assert not store.is_pristine(), f"State does not exists yet: {state_file}"
# Make a backup
# https://stackoverflow.com/a/47528275/315168
backup_file = None
for i in range(1, 20): # Try 20 different iterateive backup filenames
backup_file = state_file.with_suffix(f".reinit-backup-{i}.json")
if os.path.exists(backup_file):
continue
state_file.rename(backup_file)
break
else:
raise RuntimeError(f"Could not create backup {backup_file}")
logger.info("Old state backed up as %s", backup_file)
state = store.create(name)
logger.info("Syncing initial strategy chain state: %s", name)
logger.info(f"Vault deployment block number hint is {start_block or 0:,}.")
assert isinstance(sync_model, EnzymeVaultSyncModel), f"reinit currently only supports EnzymeVaultSyncModel, got {sync_model}"
# Perform reconstruction of state
sync_model.sync_reinit(state, start_block=start_block)
store.sync(state)
web3config.close()
reserve_position = state.portfolio.get_default_reserve_position()
asset, rate = state.portfolio.get_default_reserve_asset()
logger.info("Reserve position is %s", reserve_position)
logger.info("Balance is %s %s", reserve_position.get_quantity(), asset.token_symbol)
assert reserve_position.quantity > 0, f"Reinitialisation did not see any deposits in vault: {sync_model.vault}, reserve position is {reserve_position}"
logger.info("All done: State deployment info is %s", state.sync.deployment)