mirror of
https://github.com/status-im/nimbus-eth2.git
synced 2025-01-16 09:34:40 +00:00
f70ff38b53
Some upstream repos still need fixes, but this gets us close enough that style hints can be enabled by default. In general, "canonical" spellings are preferred even if they violate nep-1 - this applies in particular to spec-related stuff like `genesis_validators_root` which appears throughout the codebase.
915 lines
32 KiB
Nim
915 lines
32 KiB
Nim
{.used.}
|
|
|
|
import
|
|
std/[os, options, json, typetraits, uri, algorithm],
|
|
unittest2, chronos, chronicles, stint, json_serialization,
|
|
blscurve, eth/keys, nimcrypto/utils,
|
|
libp2p/crypto/crypto as lcrypto,
|
|
stew/[io2, byteutils],
|
|
../beacon_chain/filepath,
|
|
../beacon_chain/networking/network_metadata,
|
|
../beacon_chain/spec/eth2_merkleization,
|
|
../beacon_chain/spec/datatypes/base,
|
|
../beacon_chain/spec/[crypto, keystore],
|
|
../beacon_chain/validators/keystore_management,
|
|
./testutil
|
|
|
|
const
|
|
simulationDepositsCount = 2
|
|
testDataDir = "./test_keystore_management"
|
|
testValidatorsDir = testDataDir / "validators"
|
|
testSecretsDir = testDataDir / "secrets"
|
|
|
|
proc directoryItemsCount(dir: string): int {.raises: [OSError].} =
|
|
for el in walkDir(dir):
|
|
result += 1
|
|
|
|
proc validatorPubKeysInDir(dir: string): seq[string] =
|
|
for kind, file in walkDir(dir):
|
|
if kind == pcDir:
|
|
result.add(splitFile(file).name)
|
|
|
|
proc contentEquals(filePath, expectedContent: string): bool =
|
|
var file: File
|
|
|
|
discard open(file, filePath)
|
|
defer: close(file)
|
|
|
|
expectedContent == readAll(file)
|
|
|
|
let
|
|
rng = keys.newRng()
|
|
mnemonic = generateMnemonic(rng[])
|
|
seed = getSeed(mnemonic, KeyStorePass.init "")
|
|
cfg = defaultRuntimeConfig
|
|
validatorDirRes = secureCreatePath(testValidatorsDir)
|
|
|
|
proc namesEqual(a, b: openArray[string]): bool =
|
|
sorted(a) == sorted(b)
|
|
|
|
when not defined(windows):
|
|
proc isEmptyDir(dir: string): bool =
|
|
directoryItemsCount(dir) == 0
|
|
|
|
if validatorDirRes.isErr():
|
|
warn "Could not create validators folder",
|
|
path = testValidatorsDir, err = ioErrorMsg(validatorDirRes.error)
|
|
|
|
let secretDirRes = secureCreatePath(testSecretsDir)
|
|
if secretDirRes.isErr():
|
|
warn "Could not create secrets folder",
|
|
path = testSecretsDir, err = ioErrorMsg(secretDirRes.error)
|
|
|
|
let deposits = generateDeposits(
|
|
cfg,
|
|
rng[],
|
|
seed,
|
|
0, simulationDepositsCount,
|
|
testValidatorsDir,
|
|
testSecretsDir)
|
|
|
|
if deposits.isErr:
|
|
fatal "Failed to generate deposits", err = deposits.error
|
|
quit 1
|
|
|
|
let validatorPubKeys = validatorPubKeysInDir(testValidatorsDir)
|
|
|
|
const
|
|
MultiplePassword = string.fromBytes(
|
|
hexToSeqByte("7465737470617373776f7264f09f9491"))
|
|
MultipleSalt = hexToSeqByte(
|
|
"d4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3")
|
|
MultipleIv = hexToSeqByte("264daa3f303d7259501c93d997d84fe6")
|
|
MultipleRemoteUri = HttpHostUri(parseUri("https://127.0.0.1/eth/web3signer"))
|
|
|
|
MultiplePrivateKeys = [
|
|
"3b89cdf5c62b423dab64dd69476c6c74bdbccc684abc89f3b392ac1f679e06c3",
|
|
"5140621611300ed419f901d8c56baf32d89d876272bbb3ab16e1c9f0884487d4"
|
|
]
|
|
|
|
var
|
|
MultipleKeystoreNames: seq[string]
|
|
MultipleSigningKeys: seq[ValidatorPrivKey]
|
|
MultipleLocalKeystores: seq[Keystore]
|
|
MultipleLocalKeystoreJsons: seq[string]
|
|
MultipleRemoteKeystores: seq[RemoteKeystore]
|
|
MultipleRemoteKeystoreJsons: seq[string]
|
|
|
|
for key in MultiplePrivateKeys:
|
|
let
|
|
nsecret = ValidatorPrivKey.fromRaw(hexToSeqByte(key)).get()
|
|
npubkey = nsecret.toPubKey().toPubKey()
|
|
keystoreName = "0x" & npubkey.toHex()
|
|
|
|
localKeystore = createKeystore(
|
|
kdfPbkdf2, rng[], nsecret,
|
|
KeystorePass.init MultiplePassword,
|
|
salt = MultipleSalt, iv = MultipleIv,
|
|
description = "This is a test keystore.",
|
|
path = validateKeyPath("m/12381/60/0/0").expect("Valid Keypath"))
|
|
localKeystoreJson = Json.encode(localKeystore)
|
|
|
|
remoteKeystore = createRemoteKeystore(npubkey, MultipleRemoteUri)
|
|
remoteKeystoreJson = Json.encode(remoteKeystore)
|
|
|
|
MultipleSigningKeys.add(nsecret)
|
|
MultipleKeystoreNames.add(keystoreName)
|
|
MultipleLocalKeystores.add(localKeystore)
|
|
MultipleLocalKeystoreJsons.add(localKeystoreJson)
|
|
MultipleRemoteKeystores.add(remoteKeystore)
|
|
MultipleRemoteKeystoreJsons.add(remoteKeystoreJson)
|
|
|
|
suite "removeValidatorFiles()":
|
|
test "Remove validator files":
|
|
let
|
|
validatorsCountBefore = directoryItemsCount(testValidatorsDir)
|
|
secretsCountBefore = directoryItemsCount(testSecretsDir)
|
|
firstValidator = validatorPubKeys[0]
|
|
removeValidatorFilesRes = removeValidatorFiles(
|
|
testValidatorsDir, testSecretsDir, firstValidator, KeystoreKind.Local)
|
|
validatorsCountAfter = directoryItemsCount(testValidatorsDir)
|
|
secretsCountAfter = directoryItemsCount(testSecretsDir)
|
|
|
|
check:
|
|
removeValidatorFilesRes.isOk
|
|
removeValidatorFilesRes.value == RemoveValidatorStatus.deleted
|
|
validatorsCountBefore - 1 == validatorsCountAfter
|
|
not fileExists(testValidatorsDir / firstValidator / KeystoreFileName)
|
|
not fileExists(testValidatorsDir / firstValidator)
|
|
secretsCountBefore - 1 == secretsCountAfter
|
|
not fileExists(testSecretsDir / firstValidator)
|
|
|
|
test "Remove nonexistent validator":
|
|
let
|
|
nonexistentValidator =
|
|
"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
|
|
res = removeValidatorFiles(testValidatorsDir, testSecretsDir,
|
|
nonexistentValidator, KeystoreKind.Local)
|
|
|
|
check(res.isOk and res.value == RemoveValidatorStatus.notFound)
|
|
|
|
test "Remove validator files twice":
|
|
let
|
|
secondValidator = validatorPubKeys[1]
|
|
res1 = removeValidatorFiles(testValidatorsDir, testSecretsDir,
|
|
secondValidator, KeystoreKind.Local)
|
|
res2 = removeValidatorFiles(testValidatorsDir, testSecretsDir,
|
|
secondValidator, KeystoreKind.Local)
|
|
|
|
check:
|
|
not fileExists(testValidatorsDir / secondValidator)
|
|
not fileExists(testSecretsDir / secondValidator)
|
|
res1.isOk and res1.value() == RemoveValidatorStatus.deleted
|
|
res2.isOk and res2.value() == RemoveValidatorStatus.notFound
|
|
|
|
os.removeDir testValidatorsDir
|
|
os.removeDir testSecretsDir
|
|
|
|
suite "removeValidatorFiles() multiple keystore types":
|
|
setup:
|
|
let
|
|
curKeystoreDir0 {.used.} = testValidatorsDir / MultipleKeystoreNames[0]
|
|
curSecretsFile0 {.used.} = testSecretsDir / MultipleKeystoreNames[0]
|
|
remoteKeystoreFile0 {.used.} = curKeystoreDir0 / RemoteKeystoreFileName
|
|
localKeystoreFile0 {.used.} = curKeystoreDir0 / KeystoreFileName
|
|
curSigningKey0 {.used.} = MultipleSigningKeys[0]
|
|
curCookedKey0 {.used.} = curSigningKey0.toPubKey()
|
|
curPublicKey0 {.used.} = curCookedKey0.toPubKey()
|
|
|
|
curKeystoreDir1 {.used.} = testValidatorsDir / MultipleKeystoreNames[1]
|
|
curSecretsFile1 {.used.} = testSecretsDir / MultipleKeystoreNames[1]
|
|
remoteKeystoreFile1 {.used.} = curKeystoreDir1 / RemoteKeystoreFileName
|
|
localKeystoreFile1 {.used.} = curKeystoreDir1 / KeystoreFileName
|
|
curSigningKey1 {.used.} = MultipleSigningKeys[1]
|
|
curCookedKey1 {.used.} = curSigningKey1.toPubKey()
|
|
curPublicKey1 {.used.} = curCookedKey1.toPubKey()
|
|
|
|
curSigningPath {.used.} =
|
|
validateKeyPath("m/12381/60/0/0").expect("Valid Keypath")
|
|
|
|
teardown:
|
|
os.removeDir testValidatorsDir
|
|
os.removeDir testSecretsDir
|
|
|
|
test "Remove [LOCAL] when [LOCAL] is present":
|
|
let
|
|
res1 = saveKeystore(rng[], testValidatorsDir, testSecretsDir,
|
|
curSigningKey0, curCookedKey0, curSigningPath,
|
|
"", mode = Fast)
|
|
validatorsCount1 = directoryItemsCount(testValidatorsDir)
|
|
secretsCount1 = directoryItemsCount(testSecretsDir)
|
|
validatorPubKeys1 = validatorPubKeysInDir(testValidatorsDir)
|
|
|
|
res2 = removeValidatorFiles(testValidatorsDir, testSecretsDir,
|
|
MultipleKeystoreNames[0], KeystoreKind.Local)
|
|
|
|
validatorsCount2 = directoryItemsCount(testValidatorsDir)
|
|
secretsCount2 = directoryItemsCount(testSecretsDir)
|
|
validatorPubKeys2 = validatorPubKeysInDir(testValidatorsDir)
|
|
|
|
check:
|
|
res1.isOk
|
|
res2.isOk
|
|
res2.value == RemoveValidatorStatus.deleted
|
|
|
|
validatorsCount1 == 1
|
|
secretsCount1 == 1
|
|
validatorsCount2 == 0
|
|
secretsCount2 == 0
|
|
|
|
not(dirExists(curKeystoreDir0))
|
|
not(fileExists(remoteKeystoreFile0))
|
|
not(fileExists(localKeystoreFile0))
|
|
not(fileExists(curSecretsFile0))
|
|
|
|
namesEqual(validatorPubKeys1, [MultipleKeystoreNames[0]])
|
|
namesEqual(validatorPubKeys2, [])
|
|
|
|
test "Remove [LOCAL] when [LOCAL] is missing":
|
|
let
|
|
res1 = saveKeystore(rng[], testValidatorsDir, testSecretsDir,
|
|
curSigningKey0, curCookedKey0, curSigningPath,
|
|
"", mode = Fast)
|
|
validatorsCount1 = directoryItemsCount(testValidatorsDir)
|
|
secretsCount1 = directoryItemsCount(testSecretsDir)
|
|
validatorPubKeys1 = validatorPubKeysInDir(testValidatorsDir)
|
|
|
|
res2 = removeValidatorFiles(testValidatorsDir, testSecretsDir,
|
|
MultipleKeystoreNames[1], KeystoreKind.Local)
|
|
|
|
validatorsCount2 = directoryItemsCount(testValidatorsDir)
|
|
secretsCount2 = directoryItemsCount(testSecretsDir)
|
|
validatorPubKeys2 = validatorPubKeysInDir(testValidatorsDir)
|
|
|
|
check:
|
|
res1.isOk
|
|
res2.isOk
|
|
res2.value == RemoveValidatorStatus.notFound
|
|
|
|
validatorsCount1 == 1
|
|
secretsCount1 == 1
|
|
validatorsCount2 == 1
|
|
secretsCount2 == 1
|
|
|
|
dirExists(curKeystoreDir0)
|
|
not(fileExists(remoteKeystoreFile0))
|
|
fileExists(localKeystoreFile0)
|
|
fileExists(curSecretsFile0)
|
|
|
|
namesEqual(validatorPubKeys1, [MultipleKeystoreNames[0]])
|
|
namesEqual(validatorPubKeys2, [MultipleKeystoreNames[0]])
|
|
|
|
test "Remove [REMOTE] when [REMOTE] is present":
|
|
let
|
|
res1 = saveKeystore(testValidatorsDir, curPublicKey0, MultipleRemoteUri)
|
|
|
|
validatorsCount1 = directoryItemsCount(testValidatorsDir)
|
|
secretsCount1 = directoryItemsCount(testSecretsDir)
|
|
validatorPubKeys1 = validatorPubKeysInDir(testValidatorsDir)
|
|
|
|
res2 = removeValidatorFiles(testValidatorsDir, testSecretsDir,
|
|
MultipleKeystoreNames[0], KeystoreKind.Remote)
|
|
|
|
validatorsCount2 = directoryItemsCount(testValidatorsDir)
|
|
secretsCount2 = directoryItemsCount(testSecretsDir)
|
|
validatorPubKeys2 = validatorPubKeysInDir(testValidatorsDir)
|
|
|
|
check:
|
|
res1.isOk
|
|
res2.isOk
|
|
res2.value == RemoveValidatorStatus.deleted
|
|
|
|
validatorsCount1 == 1
|
|
secretsCount1 == 0
|
|
validatorsCount2 == 0
|
|
secretsCount2 == 0
|
|
|
|
not(dirExists(curKeystoreDir0))
|
|
not(fileExists(remoteKeystoreFile0))
|
|
not(fileExists(localKeystoreFile0))
|
|
not(fileExists(curSecretsFile0))
|
|
|
|
namesEqual(validatorPubKeys1, [MultipleKeystoreNames[0]])
|
|
namesEqual(validatorPubKeys2, [])
|
|
|
|
test "Remove [REMOTE] when [REMOTE] is missing":
|
|
let
|
|
res1 = saveKeystore(testValidatorsDir, curPublicKey0, MultipleRemoteUri)
|
|
|
|
validatorsCount1 = directoryItemsCount(testValidatorsDir)
|
|
secretsCount1 = directoryItemsCount(testSecretsDir)
|
|
validatorPubKeys1 = validatorPubKeysInDir(testValidatorsDir)
|
|
|
|
res2 = removeValidatorFiles(testValidatorsDir, testSecretsDir,
|
|
MultipleKeystoreNames[1], KeystoreKind.Remote)
|
|
|
|
validatorsCount2 = directoryItemsCount(testValidatorsDir)
|
|
secretsCount2 = directoryItemsCount(testSecretsDir)
|
|
validatorPubKeys2 = validatorPubKeysInDir(testValidatorsDir)
|
|
|
|
check:
|
|
res1.isOk
|
|
res2.isOk
|
|
res2.value == RemoveValidatorStatus.notFound
|
|
|
|
validatorsCount1 == 1
|
|
secretsCount1 == 0
|
|
validatorsCount2 == 1
|
|
secretsCount2 == 0
|
|
|
|
dirExists(curKeystoreDir0)
|
|
fileExists(remoteKeystoreFile0)
|
|
not(fileExists(localKeystoreFile0))
|
|
not(fileExists(curSecretsFile0))
|
|
|
|
namesEqual(validatorPubKeys1, [MultipleKeystoreNames[0]])
|
|
namesEqual(validatorPubKeys2, [MultipleKeystoreNames[0]])
|
|
|
|
test "Remove [LOCAL] when [REMOTE] is present":
|
|
let
|
|
res1 = saveKeystore(testValidatorsDir, curPublicKey0, MultipleRemoteUri)
|
|
|
|
validatorsCount1 = directoryItemsCount(testValidatorsDir)
|
|
secretsCount1 = directoryItemsCount(testSecretsDir)
|
|
validatorPubKeys1 = validatorPubKeysInDir(testValidatorsDir)
|
|
|
|
res2 = removeValidatorFiles(testValidatorsDir, testSecretsDir,
|
|
MultipleKeystoreNames[0], KeystoreKind.Local)
|
|
|
|
validatorsCount2 = directoryItemsCount(testValidatorsDir)
|
|
secretsCount2 = directoryItemsCount(testSecretsDir)
|
|
validatorPubKeys2 = validatorPubKeysInDir(testValidatorsDir)
|
|
|
|
check:
|
|
res1.isOk
|
|
res2.isOk
|
|
res2.value == RemoveValidatorStatus.notFound
|
|
|
|
validatorsCount1 == 1
|
|
secretsCount1 == 0
|
|
validatorsCount2 == 1
|
|
secretsCount2 == 0
|
|
|
|
dirExists(curKeystoreDir0)
|
|
fileExists(remoteKeystoreFile0)
|
|
not(fileExists(localKeystoreFile0))
|
|
not(fileExists(curSecretsFile0))
|
|
|
|
namesEqual(validatorPubKeys1, [MultipleKeystoreNames[0]])
|
|
namesEqual(validatorPubKeys2, [MultipleKeystoreNames[0]])
|
|
|
|
test "Remove [REMOTE] when [LOCAL] is present":
|
|
let
|
|
res1 = saveKeystore(rng[], testValidatorsDir, testSecretsDir,
|
|
curSigningKey0, curCookedKey0, curSigningPath,
|
|
"", mode = Fast)
|
|
validatorsCount1 = directoryItemsCount(testValidatorsDir)
|
|
secretsCount1 = directoryItemsCount(testSecretsDir)
|
|
validatorPubKeys1 = validatorPubKeysInDir(testValidatorsDir)
|
|
|
|
res2 = removeValidatorFiles(testValidatorsDir, testSecretsDir,
|
|
MultipleKeystoreNames[0], KeystoreKind.Remote)
|
|
|
|
validatorsCount2 = directoryItemsCount(testValidatorsDir)
|
|
secretsCount2 = directoryItemsCount(testSecretsDir)
|
|
validatorPubKeys2 = validatorPubKeysInDir(testValidatorsDir)
|
|
|
|
check:
|
|
res1.isOk
|
|
res2.isOk
|
|
res2.value == RemoveValidatorStatus.notFound
|
|
|
|
validatorsCount1 == 1
|
|
secretsCount1 == 1
|
|
validatorsCount2 == 1
|
|
secretsCount2 == 1
|
|
|
|
dirExists(curKeystoreDir0)
|
|
not(fileExists(remoteKeystoreFile0))
|
|
fileExists(localKeystoreFile0)
|
|
fileExists(curSecretsFile0)
|
|
|
|
namesEqual(validatorPubKeys1, [MultipleKeystoreNames[0]])
|
|
namesEqual(validatorPubKeys2, [MultipleKeystoreNames[0]])
|
|
|
|
os.removeDir testValidatorsDir
|
|
os.removeDir testSecretsDir
|
|
|
|
suite "createValidatorFiles()":
|
|
setup:
|
|
const
|
|
password = string.fromBytes hexToSeqByte("7465737470617373776f7264f09f9491")
|
|
secretBytes = hexToSeqByte "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f"
|
|
salt = hexToSeqByte "d4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3"
|
|
iv = hexToSeqByte "264daa3f303d7259501c93d997d84fe6"
|
|
|
|
let
|
|
secret = ValidatorPrivKey.fromRaw(secretBytes).get
|
|
|
|
keystore = createKeystore(
|
|
kdfPbkdf2, rng[], secret,
|
|
KeystorePass.init password,
|
|
salt=salt, iv=iv,
|
|
description = "This is a test keystore that uses PBKDF2 to secure the secret.",
|
|
path = validateKeyPath("m/12381/60/0/0").expect("Valid Keypath"))
|
|
keystoreJsonContents {.used.} = Json.encode(keystore)
|
|
|
|
hexEncodedPubkey = "0x" & keystore.pubkey.toHex()
|
|
keystoreDir {.used.} = testValidatorsDir / hexEncodedPubkey
|
|
secretFile {.used.} = testSecretsDir / hexEncodedPubkey
|
|
keystoreFile {.used.} = testValidatorsDir / hexEncodedPubkey /
|
|
KeystoreFileName
|
|
|
|
teardown:
|
|
os.removeDir testValidatorsDir
|
|
os.removeDir testSecretsDir
|
|
|
|
test "Add keystore files [LOCAL]":
|
|
let
|
|
res = createValidatorFiles(testSecretsDir, testValidatorsDir,
|
|
keystoreDir,
|
|
secretFile, password,
|
|
keystoreFile, keystoreJsonContents)
|
|
|
|
validatorsCount = directoryItemsCount(testValidatorsDir)
|
|
secretsCount = directoryItemsCount(testSecretsDir)
|
|
|
|
validatorPubKeys = validatorPubKeysInDir(testValidatorsDir)
|
|
|
|
check:
|
|
res.isOk
|
|
|
|
validatorsCount == 1
|
|
secretsCount == 1
|
|
|
|
dirExists(testValidatorsDir / hexEncodedPubkey)
|
|
fileExists(testSecretsDir / hexEncodedPubkey)
|
|
|
|
secretFile.contentEquals password
|
|
keystoreFile.contentEquals keystoreJsonContents
|
|
|
|
namesEqual(validatorPubKeys, [hexEncodedPubkey])
|
|
|
|
test "Add keystore files twice [LOCAL]":
|
|
let
|
|
res1 = createValidatorFiles(testSecretsDir, testValidatorsDir,
|
|
keystoreDir,
|
|
secretFile, password,
|
|
keystoreFile, keystoreJsonContents)
|
|
|
|
res2 = createValidatorFiles(testSecretsDir, testValidatorsDir,
|
|
keystoreDir,
|
|
secretFile, password,
|
|
keystoreFile, keystoreJsonContents)
|
|
|
|
validatorsCount = directoryItemsCount(testValidatorsDir)
|
|
secretsCount = directoryItemsCount(testSecretsDir)
|
|
validatorPubKeys = validatorPubKeysInDir(testValidatorsDir)
|
|
|
|
check:
|
|
res1.isOk
|
|
res2.isOk # The second call should just overwrite the results of the first
|
|
|
|
validatorsCount == 1
|
|
secretsCount == 1
|
|
|
|
dirExists(testValidatorsDir / hexEncodedPubkey)
|
|
fileExists(testSecretsDir / hexEncodedPubkey)
|
|
secretFile.contentEquals password
|
|
keystoreFile.contentEquals keystoreJsonContents
|
|
|
|
namesEqual(validatorPubKeys, [hexEncodedPubkey])
|
|
|
|
test "Add keystore files [REMOTE]":
|
|
let
|
|
curKeystoreDir = testValidatorsDir / MultipleKeystoreNames[0]
|
|
curSecretsFile = testSecretsDir / MultipleKeystoreNames[0]
|
|
remoteKeystoreFile = curKeystoreDir / RemoteKeystoreFileName
|
|
localKeystoreFile = curKeystoreDir / KeystoreFileName
|
|
|
|
res = createValidatorFiles(testValidatorsDir, curKeystoreDir,
|
|
remoteKeystoreFile,
|
|
MultipleRemoteKeystoreJsons[0])
|
|
|
|
validatorsCount = directoryItemsCount(testValidatorsDir)
|
|
secretsCount = directoryItemsCount(testSecretsDir)
|
|
|
|
validatorPubKeys = validatorPubKeysInDir(testValidatorsDir)
|
|
|
|
check:
|
|
res.isOk
|
|
|
|
validatorsCount == 1
|
|
secretsCount == 0
|
|
|
|
dirExists(curKeystoreDir)
|
|
fileExists(remoteKeystoreFile)
|
|
not(fileExists(localKeystoreFile))
|
|
not(fileExists(curSecretsFile))
|
|
|
|
remoteKeystoreFile.contentEquals MultipleRemoteKeystoreJsons[0]
|
|
|
|
|
|
namesEqual(validatorPubKeys, [MultipleKeystoreNames[0]])
|
|
|
|
test "Add keystore files twice [REMOTE]":
|
|
let
|
|
curKeystoreDir = testValidatorsDir / MultipleKeystoreNames[0]
|
|
curSecretsFile = testSecretsDir / MultipleKeystoreNames[0]
|
|
remoteKeystoreFile = curKeystoreDir / RemoteKeystoreFileName
|
|
localKeystoreFile = curKeystoreDir / KeystoreFileName
|
|
|
|
res1 = createValidatorFiles(testValidatorsDir, curKeystoreDir,
|
|
remoteKeystoreFile,
|
|
MultipleRemoteKeystoreJsons[0])
|
|
|
|
res2 = createValidatorFiles(testValidatorsDir, curKeystoreDir,
|
|
remoteKeystoreFile,
|
|
MultipleRemoteKeystoreJsons[0])
|
|
|
|
validatorsCount = directoryItemsCount(testValidatorsDir)
|
|
secretsCount = directoryItemsCount(testSecretsDir)
|
|
|
|
validatorPubKeys = validatorPubKeysInDir(testValidatorsDir)
|
|
|
|
check:
|
|
res1.isOk
|
|
res2.isOk # The second call should just overwrite the results of the first
|
|
|
|
validatorsCount == 1
|
|
secretsCount == 0
|
|
|
|
dirExists(curKeystoreDir)
|
|
fileExists(remoteKeystoreFile)
|
|
not(fileExists(localKeystoreFile))
|
|
not(fileExists(curSecretsFile))
|
|
|
|
remoteKeystoreFile.contentEquals MultipleRemoteKeystoreJsons[0]
|
|
|
|
namesEqual(validatorPubKeys, [MultipleKeystoreNames[0]])
|
|
|
|
# TODO The following tests are disabled on Windows because the io2 module
|
|
# doesn't implement the permission/mode parameter at the moment:
|
|
when not defined(windows):
|
|
test "`createValidatorFiles` with `secretsDir` without permissions":
|
|
# Creating `secrets` dir with `UserRead` permissions before
|
|
# calling `createValidatorFiles` which should result in problem
|
|
# with creating a secret file inside the dir:
|
|
let
|
|
secretsDirNoPermissions = createPath(testSecretsDir, 0o400)
|
|
res = createValidatorFiles(testSecretsDir, testValidatorsDir,
|
|
keystoreDir,
|
|
secretFile, password,
|
|
keystoreFile, keystoreJsonContents)
|
|
check:
|
|
res.isErr and res.error.kind == FailedToCreateSecretFile
|
|
|
|
# The secrets dir was pre-existing, so it should be preserved and
|
|
# it should remain empty:
|
|
dirExists(testSecretsDir)
|
|
testSecretsDir.isEmptyDir
|
|
|
|
# The creation of the validators dir should be rolled-back
|
|
not dirExists(testValidatorsDir)
|
|
|
|
test "`createValidatorFiles` with `validatorsDir` without permissions":
|
|
# Creating `validators` dir with `UserRead` permissions before
|
|
# calling `createValidatorFiles` which should result in problems
|
|
# creating `keystoreDir` inside the dir.
|
|
let
|
|
validatorsDirNoPermissions = createPath(testValidatorsDir, 0o400)
|
|
res = createValidatorFiles(testSecretsDir, testValidatorsDir,
|
|
keystoreDir,
|
|
secretFile, password,
|
|
keystoreFile, keystoreJsonContents)
|
|
check:
|
|
res.isErr and res.error.kind == FailedToCreateKeystoreDir
|
|
|
|
# The creation of the secrets dir should be rolled-back
|
|
not dirExists(testSecretsDir)
|
|
|
|
# The validators dir was pre-existing, so it should be preserved and
|
|
# it should remain empty:
|
|
dirExists(testValidatorsDir)
|
|
testValidatorsDir.isEmptyDir
|
|
|
|
test "`createValidatorFiles` with `keystoreDir` without permissions":
|
|
# Creating `keystore` dir with `UserRead` permissions before
|
|
# calling `createValidatorFiles` which should result in problems
|
|
# creating keystore file inside this dir:
|
|
let
|
|
validatorsDir = createPath(testValidatorsDir, 0o700)
|
|
keystoreDirNoPermissions = createPath(keystoreDir, 0o400)
|
|
res = createValidatorFiles(testSecretsDir, testValidatorsDir,
|
|
keystoreDir,
|
|
secretFile, password,
|
|
keystoreFile, keystoreJsonContents)
|
|
check:
|
|
res.isErr and res.error.kind == FailedToCreateKeystoreFile
|
|
|
|
not dirExists(testSecretsDir)
|
|
|
|
dirExists(testValidatorsDir)
|
|
not fileExists(testValidatorsDir / hexEncodedPubkey)
|
|
testValidatorsDir.isEmptyDir
|
|
|
|
test "`createValidatorFiles` with already existing dirs and any error":
|
|
# Generate deposits so we have files and dirs already existing
|
|
# before testing `createValidatorFiles` failure
|
|
let
|
|
deposits = generateDeposits(
|
|
cfg,
|
|
rng[],
|
|
seed,
|
|
0, simulationDepositsCount,
|
|
testValidatorsDir,
|
|
testSecretsDir)
|
|
|
|
validatorsCountBefore = directoryItemsCount(testValidatorsDir)
|
|
secretsCountBefore = directoryItemsCount(testSecretsDir)
|
|
|
|
# Creating `keystore` dir with `UserRead` permissions before calling `createValidatorFiles`
|
|
# which will result in error
|
|
keystoreDirNoPermissions = createPath(keystoreDir, 0o400)
|
|
|
|
res = createValidatorFiles(testSecretsDir, testValidatorsDir,
|
|
keystoreDir,
|
|
secretFile, password,
|
|
keystoreFile, keystoreJsonContents)
|
|
|
|
validatorsCountAfter = directoryItemsCount(testValidatorsDir)
|
|
secretsCountAfter = directoryItemsCount(testSecretsDir)
|
|
|
|
check:
|
|
res.isErr
|
|
|
|
# `secrets` & `validators` should be removed during the roll-back:
|
|
dirExists(testSecretsDir)
|
|
dirExists(testValidatorsDir)
|
|
|
|
# The number of directies should not have changed after the failure:
|
|
validatorsCountBefore == validatorsCountAfter
|
|
secretsCountBefore == secretsCountAfter
|
|
|
|
os.removeDir testDataDir
|
|
|
|
suite "saveKeystore()":
|
|
setup:
|
|
let
|
|
curKeystoreDir0 = testValidatorsDir / MultipleKeystoreNames[0]
|
|
curSecretsFile0 = testSecretsDir / MultipleKeystoreNames[0]
|
|
remoteKeystoreFile0 = curKeystoreDir0 / RemoteKeystoreFileName
|
|
localKeystoreFile0 = curKeystoreDir0 / KeystoreFileName
|
|
curSigningKey0 = MultipleSigningKeys[0]
|
|
curCookedKey0 = curSigningKey0.toPubKey()
|
|
curPublicKey0 {.used.} = curCookedKey0.toPubKey()
|
|
|
|
curKeystoreDir1 = testValidatorsDir / MultipleKeystoreNames[1]
|
|
curSecretsFile1 {.used.} = testSecretsDir / MultipleKeystoreNames[1]
|
|
remoteKeystoreFile1 {.used.} = curKeystoreDir1 / RemoteKeystoreFileName
|
|
localKeystoreFile1 {.used.} = curKeystoreDir1 / KeystoreFileName
|
|
curSigningKey1 = MultipleSigningKeys[1]
|
|
curCookedKey1 = curSigningKey1.toPubKey()
|
|
curPublicKey1 {.used.} = curCookedKey1.toPubKey()
|
|
|
|
curSigningPath {.used.} =
|
|
validateKeyPath("m/12381/60/0/0").expect("Valid Keypath")
|
|
|
|
teardown:
|
|
os.removeDir testValidatorsDir
|
|
os.removeDir testSecretsDir
|
|
|
|
test "Save [LOCAL] keystore after [LOCAL] keystore with same id":
|
|
let
|
|
res1 = saveKeystore(rng[], testValidatorsDir, testSecretsDir,
|
|
curSigningKey0, curCookedKey0, curSigningPath,
|
|
"", mode = Fast)
|
|
res2 = saveKeystore(rng[], testValidatorsDir, testSecretsDir,
|
|
curSigningKey0, curCookedKey0, curSigningPath,
|
|
"", mode = Fast)
|
|
validatorsCount = directoryItemsCount(testValidatorsDir)
|
|
secretsCount = directoryItemsCount(testSecretsDir)
|
|
|
|
validatorPubKeys = validatorPubKeysInDir(testValidatorsDir)
|
|
|
|
check:
|
|
res1.isOk
|
|
res2.isErr
|
|
res2.error().kind == DuplicateKeystoreDir
|
|
|
|
validatorsCount == 1
|
|
secretsCount == 1
|
|
|
|
dirExists(curKeystoreDir0)
|
|
not(fileExists(remoteKeystoreFile0))
|
|
fileExists(localKeystoreFile0)
|
|
fileExists(curSecretsFile0)
|
|
|
|
namesEqual(validatorPubKeys, [MultipleKeystoreNames[0]])
|
|
|
|
test "Save [REMOTE] keystore after [REMOTE] keystore with same id":
|
|
let
|
|
res1 = saveKeystore(testValidatorsDir, curPublicKey0, MultipleRemoteUri)
|
|
res2 = saveKeystore(testValidatorsDir, curPublicKey0, MultipleRemoteUri)
|
|
|
|
validatorsCount = directoryItemsCount(testValidatorsDir)
|
|
secretsCount = directoryItemsCount(testSecretsDir)
|
|
|
|
validatorPubKeys = validatorPubKeysInDir(testValidatorsDir)
|
|
|
|
check:
|
|
res1.isOk
|
|
res2.isErr
|
|
res2.error().kind == DuplicateKeystoreDir
|
|
|
|
validatorsCount == 1
|
|
secretsCount == 0
|
|
|
|
dirExists(curKeystoreDir0)
|
|
fileExists(remoteKeystoreFile0)
|
|
not(fileExists(localKeystoreFile0))
|
|
not(fileExists(curSecretsFile0))
|
|
|
|
namesEqual(validatorPubKeys, [MultipleKeystoreNames[0]])
|
|
|
|
test "Save [REMOTE] keystore after [LOCAL] keystore with same id":
|
|
let
|
|
res1 = saveKeystore(rng[], testValidatorsDir, testSecretsDir,
|
|
curSigningKey0, curCookedKey0, curSigningPath,
|
|
"", mode = Fast)
|
|
res2 = saveKeystore(testValidatorsDir, curPublicKey0, MultipleRemoteUri)
|
|
|
|
validatorsCount = directoryItemsCount(testValidatorsDir)
|
|
secretsCount = directoryItemsCount(testSecretsDir)
|
|
|
|
validatorPubKeys = validatorPubKeysInDir(testValidatorsDir)
|
|
|
|
check:
|
|
res1.isOk
|
|
res2.isErr
|
|
res2.error().kind == DuplicateKeystoreDir
|
|
|
|
validatorsCount == 1
|
|
secretsCount == 1
|
|
|
|
dirExists(curKeystoreDir0)
|
|
not(fileExists(remoteKeystoreFile0))
|
|
fileExists(localKeystoreFile0)
|
|
fileExists(curSecretsFile0)
|
|
|
|
namesEqual(validatorPubKeys, [MultipleKeystoreNames[0]])
|
|
|
|
test "Save [LOCAL] keystore after [REMOTE] keystore with same id":
|
|
let
|
|
res1 = saveKeystore(testValidatorsDir, curPublicKey0, MultipleRemoteUri)
|
|
res2 = saveKeystore(rng[], testValidatorsDir, testSecretsDir,
|
|
curSigningKey0, curCookedKey0, curSigningPath,
|
|
"", mode = Fast)
|
|
|
|
validatorsCount = directoryItemsCount(testValidatorsDir)
|
|
secretsCount = directoryItemsCount(testSecretsDir)
|
|
|
|
validatorPubKeys = validatorPubKeysInDir(testValidatorsDir)
|
|
|
|
check:
|
|
res1.isOk
|
|
res2.isErr
|
|
res2.error().kind == DuplicateKeystoreDir
|
|
|
|
validatorsCount == 1
|
|
secretsCount == 0
|
|
|
|
dirExists(curKeystoreDir0)
|
|
fileExists(remoteKeystoreFile0)
|
|
not(fileExists(localKeystoreFile0))
|
|
not(fileExists(curSecretsFile0))
|
|
|
|
namesEqual(validatorPubKeys, [MultipleKeystoreNames[0]])
|
|
|
|
test "Save [LOCAL] keystore after [LOCAL] keystore with different id":
|
|
let
|
|
res1 = saveKeystore(rng[], testValidatorsDir, testSecretsDir,
|
|
curSigningKey0, curCookedKey0, curSigningPath,
|
|
"", mode = Fast)
|
|
res2 = saveKeystore(rng[], testValidatorsDir, testSecretsDir,
|
|
curSigningKey1, curCookedKey1, curSigningPath,
|
|
"", mode = Fast)
|
|
validatorsCount = directoryItemsCount(testValidatorsDir)
|
|
secretsCount = directoryItemsCount(testSecretsDir)
|
|
|
|
validatorPubKeys = validatorPubKeysInDir(testValidatorsDir)
|
|
|
|
check:
|
|
res1.isOk
|
|
res2.isOk
|
|
|
|
validatorsCount == 2
|
|
secretsCount == 2
|
|
|
|
dirExists(curKeystoreDir0)
|
|
not(fileExists(remoteKeystoreFile0))
|
|
fileExists(localKeystoreFile0)
|
|
fileExists(curSecretsFile0)
|
|
|
|
dirExists(curKeystoreDir1)
|
|
not(fileExists(remoteKeystoreFile1))
|
|
fileExists(localKeystoreFile1)
|
|
fileExists(curSecretsFile1)
|
|
|
|
namesEqual(validatorPubKeys,
|
|
[MultipleKeystoreNames[0], MultipleKeystoreNames[1]])
|
|
|
|
test "Save [REMOTE] keystore after [REMOTE] keystore with different id":
|
|
let
|
|
res1 = saveKeystore(testValidatorsDir, curPublicKey0, MultipleRemoteUri)
|
|
res2 = saveKeystore(testValidatorsDir, curPublicKey1, MultipleRemoteUri)
|
|
|
|
validatorsCount = directoryItemsCount(testValidatorsDir)
|
|
secretsCount = directoryItemsCount(testSecretsDir)
|
|
|
|
validatorPubKeys = validatorPubKeysInDir(testValidatorsDir)
|
|
|
|
check:
|
|
res1.isOk
|
|
res2.isOk
|
|
|
|
validatorsCount == 2
|
|
secretsCount == 0
|
|
|
|
dirExists(curKeystoreDir0)
|
|
fileExists(remoteKeystoreFile0)
|
|
not(fileExists(localKeystoreFile0))
|
|
not(fileExists(curSecretsFile0))
|
|
|
|
dirExists(curKeystoreDir1)
|
|
fileExists(remoteKeystoreFile1)
|
|
not(fileExists(localKeystoreFile1))
|
|
not(fileExists(curSecretsFile1))
|
|
|
|
namesEqual(validatorPubKeys,
|
|
[MultipleKeystoreNames[0], MultipleKeystoreNames[1]])
|
|
|
|
test "Save [LOCAL] keystore after [REMOTE] keystore with different id":
|
|
let
|
|
res1 = saveKeystore(testValidatorsDir, curPublicKey0, MultipleRemoteUri)
|
|
res2 = saveKeystore(rng[], testValidatorsDir, testSecretsDir,
|
|
curSigningKey1, curCookedKey1, curSigningPath,
|
|
"", mode = Fast)
|
|
|
|
validatorsCount = directoryItemsCount(testValidatorsDir)
|
|
secretsCount = directoryItemsCount(testSecretsDir)
|
|
|
|
validatorPubKeys = validatorPubKeysInDir(testValidatorsDir)
|
|
|
|
check:
|
|
res1.isOk
|
|
res2.isOk
|
|
|
|
validatorsCount == 2
|
|
secretsCount == 1
|
|
|
|
dirExists(curKeystoreDir0)
|
|
fileExists(remoteKeystoreFile0)
|
|
not(fileExists(localKeystoreFile0))
|
|
not(fileExists(curSecretsFile0))
|
|
|
|
dirExists(curKeystoreDir1)
|
|
not(fileExists(remoteKeystoreFile1))
|
|
fileExists(localKeystoreFile1)
|
|
fileExists(curSecretsFile1)
|
|
|
|
namesEqual(validatorPubKeys,
|
|
[MultipleKeystoreNames[0], MultipleKeystoreNames[1]])
|
|
|
|
test "Save [REMOTE] keystore after [LOCAL] keystore with different id":
|
|
let
|
|
res1 = saveKeystore(rng[], testValidatorsDir, testSecretsDir,
|
|
curSigningKey0, curCookedKey0, curSigningPath,
|
|
"", mode = Fast)
|
|
res2 = saveKeystore(testValidatorsDir, curPublicKey1, MultipleRemoteUri)
|
|
|
|
validatorsCount = directoryItemsCount(testValidatorsDir)
|
|
secretsCount = directoryItemsCount(testSecretsDir)
|
|
|
|
validatorPubKeys = validatorPubKeysInDir(testValidatorsDir)
|
|
|
|
check:
|
|
res1.isOk
|
|
res2.isOk
|
|
|
|
validatorsCount == 2
|
|
secretsCount == 1
|
|
|
|
dirExists(curKeystoreDir0)
|
|
not(fileExists(remoteKeystoreFile0))
|
|
fileExists(localKeystoreFile0)
|
|
fileExists(curSecretsFile0)
|
|
|
|
dirExists(curKeystoreDir1)
|
|
fileExists(remoteKeystoreFile1)
|
|
not(fileExists(localKeystoreFile1))
|
|
not(fileExists(curSecretsFile1))
|
|
|
|
namesEqual(validatorPubKeys,
|
|
[MultipleKeystoreNames[0], MultipleKeystoreNames[1]])
|