From 2a94f6eca6f4fd621301c02cbf07a1a25982ea63 Mon Sep 17 00:00:00 2001 From: Zahary Karadjov Date: Tue, 28 Jul 2020 23:37:12 +0300 Subject: [PATCH] medalla-deposit target capable of executing mass deposits --- Makefile | 28 ++++++++++--- beacon_chain/deposit_contract.nim | 67 +++++++++++++++++-------------- vendor/eth2-testnets | 2 +- vendor/nim-json-serialization | 2 +- vendor/nim-web3 | 2 +- 5 files changed, 63 insertions(+), 38 deletions(-) diff --git a/Makefile b/Makefile index 08af90ab2..41aaf39d4 100644 --- a/Makefile +++ b/Makefile @@ -96,6 +96,7 @@ ifeq ($(OS), Windows_NT) endif CHRONICLES_PARAMS := -d:chronicles_log_level=$(BUILD_LOG_LEVEL) +DEPOSITS_DELAY := 0 # "--define:release" implies "--stacktrace:off" and it cannot be added to config.nims ifeq ($(USE_LIBBACKTRACE), 0) @@ -211,6 +212,22 @@ medalla-deposit-data: | beacon_node deposit_contract --out-deposits-file=medalla-deposits_data-$$(date +"%Y%m%d%H%M%S").json \ --count=$(VALIDATORS) +medalla-deposit: | beacon_node deposit_contract + build/beacon_node deposits create \ + --network=medalla \ + --out-deposits-file=nbc-medalla-deposits.json \ + --new-wallet-file=build/data/shared_medalla_$(NODE_ID)/wallet.json \ + --out-deposits-dir=build/data/shared_medalla_$(NODE_ID)/validators \ + --out-secrets-dir=build/data/shared_medalla_$(NODE_ID)/secrets \ + --count=$(VALIDATORS) + + build/deposit_contract sendDeposits \ + --web3-url=$(GOERLI_WEB3_URL) \ + --deposit-contract=$$(cat vendor/eth2-testnets/shared/medalla/deposit_contract.txt) \ + --deposits-file=nbc-medalla-deposits.json \ + --min-delay=$(DEPOSITS_DELAY) \ + --ask-for-key + clean-medalla: rm -rf build/data/shared_medalla* @@ -249,18 +266,19 @@ altona-dev: | beacon_node altona-deposit: | beacon_node deposit_contract build/beacon_node deposits create \ + --network=altona \ --out-deposits-file=nbc-altona-deposits.json \ + --new-wallet-file=build/data/shared_algona_$(NODE_ID)/wallet.json \ + --out-deposits-dir=build/data/shared_altona_$(NODE_ID)/validators \ + --out-secrets-dir=build/data/shared_altona_$(NODE_ID)/secrets \ --count=$(VALIDATORS) - # TODO - # The --min-delay is needed only until we fix the invalid - # nonce generation on multiple transactions in web3 build/deposit_contract sendDeposits \ --web3-url=$(GOERLI_WEB3_URL) \ --deposit-contract=$$(cat vendor/eth2-testnets/shared/altona/deposit_contract.txt) \ --deposits-file=nbc-altona-deposits.json \ - --ask-for-key \ - --min-delay=60 + --min-delay=$(DEPOSITS_DELAY) \ + --ask-for-key clean-altona: rm -rf build/data/shared_altona* diff --git a/beacon_chain/deposit_contract.nim b/beacon_chain/deposit_contract.nim index 16be89086..6dd271092 100644 --- a/beacon_chain/deposit_contract.nim +++ b/beacon_chain/deposit_contract.nim @@ -119,6 +119,15 @@ type proc ethToWei(eth: UInt256): UInt256 = eth * 1000000000000000000.u256 +proc initWeb3(web3Url, privateKey: string): Future[Web3] {.async.} = + result = await newWeb3(web3Url) + if privateKey.len != 0: + result.privateKey = some(PrivateKey.fromHex(privateKey)[]) + else: + let accounts = await result.provider.eth_accounts() + doAssert(accounts.len > 0) + result.defaultAccount = accounts[0] + # TODO: async functions should note take `seq` inputs because # this leads to full copies. proc sendDeposits*(deposits: seq[LaunchPadDeposit], @@ -129,29 +138,31 @@ proc sendDeposits*(deposits: seq[LaunchPadDeposit], web3 = web3Url, depositContract = depositContractAddress - var web3 = await newWeb3(web3Url) - if privateKey.len != 0: - web3.privateKey = some(PrivateKey.fromHex(privateKey).tryGet) - else: - let accounts = await web3.provider.eth_accounts() - if accounts.len == 0: - error "No account offered by the web3 provider", web3Url - return - web3.defaultAccount = accounts[0] - + var web3 = await initWeb3(web3Url, privateKey) let depositContract = web3.contractSender(DepositContract, Address depositContractAddress) - for i, dp in deposits: - let status = await depositContract.deposit( - Bytes48(dp.pubKey.toRaw()), - Bytes32(dp.withdrawal_credentials.data), - Bytes96(dp.signature.toRaw()), - FixedBytes[32](hash_tree_root(dp).data)).send(value = 32.u256.ethToWei, gasPrice = 1) + for i, launchPadDeposit in deposits: + let dp = launchPadDeposit as DepositData - info "Deposit sent", status = $status + while true: + try: + let tx = depositContract.deposit( + Bytes48(dp.pubKey.toRaw()), + Bytes32(dp.withdrawal_credentials.data), + Bytes96(dp.signature.toRaw()), + FixedBytes[32](hash_tree_root(dp).data)) - if delayGenerator != nil: - await sleepAsync(delayGenerator()) + let status = await tx.send(value = 32.u256.ethToWei, gasPrice = 1) + + info "Deposit sent", status = $status + + if delayGenerator != nil: + await sleepAsync(delayGenerator()) + + break + except CatchableError as err: + await sleepAsync(60.seconds) + web3 = await initWeb3(web3Url, privateKey) proc main() {.async.} = var cfg = CliConfig.load() @@ -209,13 +220,7 @@ proc main() {.async.} = if privateKey.len > 0: cfg.privateKey = privateKey.string - let web3 = await newWeb3(cfg.web3Url) - if cfg.privateKey.len != 0: - web3.privateKey = some(PrivateKey.fromHex(cfg.privateKey)[]) - else: - let accounts = await web3.provider.eth_accounts() - doAssert(accounts.len > 0) - web3.defaultAccount = accounts[0] + let web3 = await initWeb3(cfg.web3Url, cfg.privateKey) case cfg.cmd of StartUpCommand.deploy: @@ -232,14 +237,16 @@ proc main() {.async.} = of StartUpCommand.sendDeposits: var delayGenerator: DelayGenerator + if not (cfg.maxDelay > 0.0): + cfg.maxDelay = cfg.minDelay + elif cfg.minDelay > cfg.maxDelay: + echo "The minimum delay should not be larger than the maximum delay" + quit 1 + if cfg.maxDelay > 0.0: delayGenerator = proc (): chronos.Duration {.gcsafe.} = chronos.milliseconds (rand(cfg.minDelay..cfg.maxDelay)*1000).int - if cfg.minDelay > cfg.maxDelay: - echo "The minimum delay should not be larger than the maximum delay" - quit 1 - await sendDeposits(deposits, cfg.web3Url, cfg.privateKey, cfg.depositContractAddress, delayGenerator) diff --git a/vendor/eth2-testnets b/vendor/eth2-testnets index 6326a51b0..e558ef88b 160000 --- a/vendor/eth2-testnets +++ b/vendor/eth2-testnets @@ -1 +1 @@ -Subproject commit 6326a51b0b6e10ab5eab992c7b089c3b78e9241f +Subproject commit e558ef88bafb4dd8367aaec01ba89eeec715b761 diff --git a/vendor/nim-json-serialization b/vendor/nim-json-serialization index d5eb9427b..9ca88fdcd 160000 --- a/vendor/nim-json-serialization +++ b/vendor/nim-json-serialization @@ -1 +1 @@ -Subproject commit d5eb9427b85c7f234b2bec2d70b962dfade1fa35 +Subproject commit 9ca88fdcd43f5a4cbc2d86caf057a7bd12575698 diff --git a/vendor/nim-web3 b/vendor/nim-web3 index 9fb271b87..0361338ce 160000 --- a/vendor/nim-web3 +++ b/vendor/nim-web3 @@ -1 +1 @@ -Subproject commit 9fb271b87697bafff9f27c73d5695d9aba648921 +Subproject commit 0361338cea1cf0c3999434c349287081ec81c133