Skip to content
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

Support for distributed keystores with multiple remotes based on threshold signatures #3616

Merged
merged 1 commit into from
May 10, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 16 additions & 1 deletion AllTests-mainnet.md
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,14 @@ OK: 4/4 Fail: 0/4 Skip: 0/4
+ Mocked start private key OK
```
OK: 3/3 Fail: 0/3 Skip: 0/3
## Key spliting
```diff
+ k < n OK
+ k == n OK
+ k == n == 100 OK
+ single share OK
```
OK: 4/4 Fail: 0/4 Skip: 0/4
## KeyStorage testing suite
```diff
+ Pbkdf2 errors OK
Expand Down Expand Up @@ -313,6 +321,13 @@ OK: 1/1 Fail: 0/1 Skip: 0/1
+ deletePeer() test OK
```
OK: 12/12 Fail: 0/12 Skip: 0/12
## Remove keystore testing suite
```diff
+ vesion 1 OK
+ vesion 2 many remotes OK
+ vesion 2 single remote OK
```
OK: 3/3 Fail: 0/3 Skip: 0/3
## Slashing Interchange tests [Preset: mainnet]
```diff
+ Slashing test: duplicate_pubkey_not_slashable.json OK
Expand Down Expand Up @@ -529,4 +544,4 @@ OK: 1/1 Fail: 0/1 Skip: 0/1
OK: 1/1 Fail: 0/1 Skip: 0/1

---TOTAL---
OK: 294/299 Fail: 0/299 Skip: 5/299
OK: 301/306 Fail: 0/306 Skip: 5/306
3 changes: 2 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -359,9 +359,10 @@ define MAKE_DEPOSIT

build/deposit_contract sendDeposits \
$(2) \
--deposit-contract=$$(cat vendor/eth2-network/shared/$(1)/deposit_contract.txt) \
--deposit-contract=$$(cat vendor/eth2-networks/shared/$(1)/deposit_contract.txt) \
--deposits-file=nbc-$(1)-deposits.json \
--min-delay=$(DEPOSITS_DELAY) \
--max-delay=$(DEPOSITS_DELAY) \
--ask-for-key
endef

Expand Down
4 changes: 3 additions & 1 deletion beacon_chain/deposits.nim
Original file line number Diff line number Diff line change
Expand Up @@ -391,7 +391,9 @@ proc doDeposits*(config: BeaconNodeConf, rng: var BrHmacDrbgContext) {.
walletPath.wallet.nextAccount,
config.totalDeposits,
config.outValidatorsDir,
config.outSecretsDir)
config.outSecretsDir,
@[], 0, 0,
KeystoreMode.Fast)

if deposits.isErr:
fatal "Failed to generate deposits", err = deposits.error
Expand Down
59 changes: 35 additions & 24 deletions beacon_chain/eth1/deposit_contract.nim
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ type

StartUpCommand {.pure.} = enum
deploy
drain
sendEth
generateSimulationDeposits
sendDeposits
Expand Down Expand Up @@ -56,11 +55,6 @@ type
of deploy:
discard

of drain:
drainedContractAddress* {.
desc: "Address of the contract to drain"
name: "deposit-contract" }: Eth1Address

of sendEth:
toAddress {.name: "to".}: Eth1Address
valueEth {.name: "eth".}: string
Expand All @@ -82,6 +76,20 @@ type
desc: "A LaunchPad deposits file to write"
name: "out-deposits-file" }: OutFile

threshold {.
defaultValue: 1
desc: "Used to generate distributed keys"
name: "threshold" }: uint32

remoteValidatorsCount {.
defaultValue: 0
desc: "The number of distributed validators validator"
name: "remote-validators-count" }: uint32

remoteSignersUrls {.
desc: "URLs of the remote signers"
name: "remote-signer" }: seq[string]

of sendDeposits:
depositsFile {.
desc: "A LaunchPad deposits file"
Expand All @@ -101,14 +109,17 @@ type
desc: "Maximum possible delay between making two deposits (in seconds)"
name: "max-delay" }: float

type
PubKeyBytes = DynamicBytes[48, 48]
WithdrawalCredentialsBytes = DynamicBytes[32, 32]
SignatureBytes = DynamicBytes[96, 96]

contract(DepositContract):
proc deposit(pubkey: Bytes48,
withdrawalCredentials: Bytes32,
signature: Bytes96,
proc deposit(pubkey: PubKeyBytes,
withdrawalCredentials: WithdrawalCredentialsBytes,
signature: SignatureBytes,
deposit_data_root: FixedBytes[32])

proc drain()

proc deployContract*(web3: Web3, code: string): Future[ReceiptObject] {.async.} =
var code = code
if code[1] notin {'x', 'X'}:
Expand Down Expand Up @@ -157,22 +168,23 @@ proc sendDeposits*(deposits: seq[LaunchPadDeposit],
depositContract = depositContractAddress

var web3 = await initWeb3(web3Url, privateKey)
let gasPrice = int(await web3.provider.eth_gasPrice()) * 2
let depositContract = web3.contractSender(DepositContract,
Address depositContractAddress)
for i, launchPadDeposit in deposits:
let dp = launchPadDeposit as DepositData
for i in 4200 ..< deposits.len:
let dp = deposits[i] as DepositData

while true:
try:
let tx = depositContract.deposit(
Bytes48(dp.pubkey.toRaw()),
Bytes32(dp.withdrawal_credentials.data),
Bytes96(dp.signature.toRaw()),
PubKeyBytes(@(dp.pubkey.toRaw())),
WithdrawalCredentialsBytes(@(dp.withdrawal_credentials.data)),
SignatureBytes(@(dp.signature.toRaw())),
FixedBytes[32](hash_tree_root(dp).data))

let status = await tx.send(value = 32.u256.ethToWei, gasPrice = 1)
let status = await tx.send(value = 32.u256.ethToWei, gasPrice = gasPrice)

info "Deposit sent", status = $status
info "Deposit sent", tx = $status

if delayGenerator != nil:
await sleepAsync(delayGenerator())
Expand Down Expand Up @@ -212,7 +224,11 @@ proc main() {.async.} =
seed,
0, conf.simulationDepositsCount,
string conf.outValidatorsDir,
string conf.outSecretsDir)
string conf.outSecretsDir,
conf.remoteSignersUrls,
conf.threshold,
conf.remoteValidatorsCount,
KeystoreMode.Fast)

if deposits.isErr:
fatal "Failed to generate deposits", err = deposits.error
Expand Down Expand Up @@ -257,11 +273,6 @@ proc main() {.async.} =
let receipt = await web3.deployContract(contractCode)
echo receipt.contractAddress.get, ";", receipt.blockHash

of StartUpCommand.drain:
let sender = web3.contractSender(DepositContract,
conf.drainedContractAddress)
discard await sender.drain().send(gasPrice = 1)

of StartUpCommand.sendEth:
echo await sendEth(web3, conf.toAddress, conf.valueEth.parseInt)

Expand Down
2 changes: 1 addition & 1 deletion beacon_chain/nimbus_signing_node.nim
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ template errorResponse(code: HttpCode, message: string): RestApiResponse =
RestApiResponse.response("{\"error\": \"" & message & "\"}", code)

template signatureResponse(code: HttpCode, signature: string): RestApiResponse =
RestApiResponse.response("{\"signature\": \"0x" & signature & "\"}", code)
RestApiResponse.response("{\"signature\": \"0x" & signature & "\"}", code, "application/json")

proc installApiHandlers*(node: SigningNode) =
var router = node.router()
Expand Down
3 changes: 3 additions & 0 deletions beacon_chain/nimbus_validator_client.nim
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,9 @@ proc initValidators(vc: ValidatorClientRef): Future[bool] {.async.} =
if pubkey in duplicates:
error "Duplicate validator's key found", validator_pubkey = pubkey
return false
elif keystore.kind == KeystoreKind.Remote:
info "Remote validator client was skipped", validator_pubkey = pubkey
continue
else:
duplicates.add(pubkey)
vc.attachedValidators.addLocalValidator(keystore)
Expand Down
Loading