Skip to content

Commit

Permalink
explicitly scope AttesterSlashing and IndexedAttestation types to pha…
Browse files Browse the repository at this point in the history
…se0 (#6224)
  • Loading branch information
tersec committed Apr 21, 2024
1 parent caa3b73 commit d139c92
Show file tree
Hide file tree
Showing 23 changed files with 69 additions and 52 deletions.
2 changes: 1 addition & 1 deletion beacon_chain/beacon_node.nim
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ type
exitQueue*: AsyncEventQueue[SignedVoluntaryExit]
blsToExecQueue*: AsyncEventQueue[SignedBLSToExecutionChange]
propSlashQueue*: AsyncEventQueue[ProposerSlashing]
attSlashQueue*: AsyncEventQueue[AttesterSlashing]
attSlashQueue*: AsyncEventQueue[phase0.AttesterSlashing]
blobSidecarQueue*: AsyncEventQueue[BlobSidecarInfoObject]
finalQueue*: AsyncEventQueue[FinalizationInfoObject]
reorgQueue*: AsyncEventQueue[ReorgInfoObject]
Expand Down
14 changes: 8 additions & 6 deletions beacon_chain/consensus_object_pools/validator_change_pool.nim
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,14 @@ type
OnProposerSlashingCallback =
proc(data: ProposerSlashing) {.gcsafe, raises: [].}
OnAttesterSlashingCallback =
proc(data: AttesterSlashing) {.gcsafe, raises: [].}
proc(data: phase0.AttesterSlashing) {.gcsafe, raises: [].}

ValidatorChangePool* = object
## The validator change pool tracks attester slashings, proposer slashings,
## voluntary exits, and BLS to execution changes that could be added to a
## proposed block.

attester_slashings*: Deque[AttesterSlashing] ## \
attester_slashings*: Deque[phase0.AttesterSlashing] ## \
## Not a function of chain DAG branch; just used as a FIFO queue for blocks

proposer_slashings*: Deque[ProposerSlashing] ## \
Expand Down Expand Up @@ -86,7 +86,8 @@ func init*(T: type ValidatorChangePool, dag: ChainDAGRef,
T(
# Allow filtering some validator change messages during block production
attester_slashings:
initDeque[AttesterSlashing](initialSize = ATTESTER_SLASHINGS_BOUND.int),
initDeque[phase0.AttesterSlashing](
initialSize = ATTESTER_SLASHINGS_BOUND.int),
proposer_slashings:
initDeque[ProposerSlashing](initialSize = PROPOSER_SLASHINGS_BOUND.int),
voluntary_exits:
Expand Down Expand Up @@ -132,7 +133,7 @@ iterator getValidatorIndices(
bls_to_execution_change: SignedBLSToExecutionChange): uint64 =
yield bls_to_execution_change.message.validator_index

func isSeen*(pool: ValidatorChangePool, msg: AttesterSlashing): bool =
func isSeen*(pool: ValidatorChangePool, msg: phase0.AttesterSlashing): bool =
for idx in getValidatorIndices(msg):
# One index is enough!
if idx notin pool.prior_seen_attester_slashed_indices:
Expand All @@ -150,7 +151,7 @@ func isSeen*(pool: ValidatorChangePool, msg: SignedBLSToExecutionChange): bool =
msg.message.validator_index in
pool.prior_seen_bls_to_execution_change_indices

func addMessage*(pool: var ValidatorChangePool, msg: AttesterSlashing) =
func addMessage*(pool: var ValidatorChangePool, msg: phase0.AttesterSlashing) =
for idx in getValidatorIndices(msg):
pool.prior_seen_attester_slashed_indices.incl idx
if pool.attestationPool != nil:
Expand Down Expand Up @@ -191,7 +192,8 @@ proc validateValidatorChangeMessage(
cfg: RuntimeConfig, state: ForkyBeaconState, msg: ProposerSlashing): bool =
check_proposer_slashing(state, msg, {}).isOk
proc validateValidatorChangeMessage(
cfg: RuntimeConfig, state: ForkyBeaconState, msg: AttesterSlashing): bool =
cfg: RuntimeConfig, state: ForkyBeaconState, msg:
phase0.AttesterSlashing): bool =
check_attester_slashing(state, msg, {}).isOk
proc validateValidatorChangeMessage(
cfg: RuntimeConfig, state: ForkyBeaconState, msg: SignedVoluntaryExit):
Expand Down
2 changes: 1 addition & 1 deletion beacon_chain/gossip_processing/eth2_processor.nim
Original file line number Diff line number Diff line change
Expand Up @@ -493,7 +493,7 @@ proc processBlsToExecutionChange*(

proc processAttesterSlashing*(
self: var Eth2Processor, src: MsgSource,
attesterSlashing: AttesterSlashing): ValidationRes =
attesterSlashing: phase0.AttesterSlashing): ValidationRes =
logScope:
attesterSlashing = shortLog(attesterSlashing)

Expand Down
2 changes: 1 addition & 1 deletion beacon_chain/gossip_processing/gossip_validation.nim
Original file line number Diff line number Diff line change
Expand Up @@ -1087,7 +1087,7 @@ proc validateBlsToExecutionChange*(

# https://github.com/ethereum/consensus-specs/blob/v1.3.0/specs/phase0/p2p-interface.md#attester_slashing
proc validateAttesterSlashing*(
pool: ValidatorChangePool, attester_slashing: AttesterSlashing):
pool: ValidatorChangePool, attester_slashing: phase0.AttesterSlashing):
Result[void, ValidationError] =
# [IGNORE] At least one index in the intersection of the attesting indices of
# each attestation has not yet been seen in any prior attester_slashing (i.e.
Expand Down
4 changes: 2 additions & 2 deletions beacon_chain/networking/eth2_network.nim
Original file line number Diff line number Diff line change
Expand Up @@ -837,7 +837,7 @@ template gossipMaxSize(T: untyped): uint32 =
# Attestation, AttesterSlashing, and SignedAggregateAndProof, which all
# have lists bounded at MAX_VALIDATORS_PER_COMMITTEE (2048) items, thus
# having max sizes significantly smaller than GOSSIP_MAX_SIZE.
elif T is phase0.Attestation or T is AttesterSlashing or
elif T is phase0.Attestation or T is phase0.AttesterSlashing or
T is SignedAggregateAndProof or T is phase0.SignedBeaconBlock or
T is altair.SignedBeaconBlock or T is SomeForkyLightClientObject:
GOSSIP_MAX_SIZE
Expand Down Expand Up @@ -2585,7 +2585,7 @@ proc broadcastVoluntaryExit*(
node.broadcast(topic, exit)

proc broadcastAttesterSlashing*(
node: Eth2Node, slashing: AttesterSlashing):
node: Eth2Node, slashing: phase0.AttesterSlashing):
Future[SendResult] {.async: (raises: [CancelledError], raw: true).} =
let topic = getAttesterSlashingsTopic(
node.forkDigestAtEpoch(node.getWallEpoch))
Expand Down
4 changes: 2 additions & 2 deletions beacon_chain/nimbus_beacon_node.nim
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,7 @@ proc initFullNode(
node.eventBus.blsToExecQueue.emit(data)
proc onProposerSlashingAdded(data: ProposerSlashing) =
node.eventBus.propSlashQueue.emit(data)
proc onAttesterSlashingAdded(data: AttesterSlashing) =
proc onAttesterSlashingAdded(data: phase0.AttesterSlashing) =
node.eventBus.attSlashQueue.emit(data)
proc onBlobSidecarAdded(data: BlobSidecar) =
node.eventBus.blobSidecarQueue.emit(
Expand Down Expand Up @@ -1773,7 +1773,7 @@ proc installMessageValidators(node: BeaconNode) =
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.5/specs/phase0/p2p-interface.md#attester_slashing
node.network.addValidator(
getAttesterSlashingsTopic(digest), proc (
attesterSlashing: AttesterSlashing
attesterSlashing: phase0.AttesterSlashing
): ValidationResult =
toValidationResult(
node.processor[].processAttesterSlashing(
Expand Down
2 changes: 1 addition & 1 deletion beacon_chain/rpc/rest_beacon_api.nim
Original file line number Diff line number Diff line change
Expand Up @@ -1257,7 +1257,7 @@ proc installBeaconApiHandlers*(router: var RestRouter, node: BeaconNode) =
block:
if contentBody.isNone():
return RestApiResponse.jsonError(Http400, EmptyRequestBodyError)
let dres = decodeBody(AttesterSlashing, contentBody.get())
let dres = decodeBody(phase0.AttesterSlashing, contentBody.get())
if dres.isErr():
return RestApiResponse.jsonError(Http400,
InvalidAttesterSlashingObjectError,
Expand Down
12 changes: 8 additions & 4 deletions beacon_chain/spec/datatypes/capella.nim
Original file line number Diff line number Diff line change
Expand Up @@ -368,7 +368,8 @@ type

# Operations
proposer_slashings*: List[ProposerSlashing, Limit MAX_PROPOSER_SLASHINGS]
attester_slashings*: List[AttesterSlashing, Limit MAX_ATTESTER_SLASHINGS]
attester_slashings*:
List[phase0.AttesterSlashing, Limit MAX_ATTESTER_SLASHINGS]
attestations*: List[Attestation, Limit MAX_ATTESTATIONS]
deposits*: List[Deposit, Limit MAX_DEPOSITS]
voluntary_exits*: List[SignedVoluntaryExit, Limit MAX_VOLUNTARY_EXITS]
Expand Down Expand Up @@ -405,7 +406,8 @@ type

# Operations
proposer_slashings*: List[TrustedProposerSlashing, Limit MAX_PROPOSER_SLASHINGS]
attester_slashings*: List[TrustedAttesterSlashing, Limit MAX_ATTESTER_SLASHINGS]
attester_slashings*:
List[phase0.TrustedAttesterSlashing, Limit MAX_ATTESTER_SLASHINGS]
attestations*: List[TrustedAttestation, Limit MAX_ATTESTATIONS]
deposits*: List[Deposit, Limit MAX_DEPOSITS]
voluntary_exits*: List[TrustedSignedVoluntaryExit, Limit MAX_VOLUNTARY_EXITS]
Expand All @@ -429,7 +431,8 @@ type

# Operations
proposer_slashings*: List[TrustedProposerSlashing, Limit MAX_PROPOSER_SLASHINGS]
attester_slashings*: List[TrustedAttesterSlashing, Limit MAX_ATTESTER_SLASHINGS]
attester_slashings*:
List[phase0.TrustedAttesterSlashing, Limit MAX_ATTESTER_SLASHINGS]
attestations*: List[TrustedAttestation, Limit MAX_ATTESTATIONS]
deposits*: List[Deposit, Limit MAX_DEPOSITS]
voluntary_exits*: List[TrustedSignedVoluntaryExit, Limit MAX_VOLUNTARY_EXITS]
Expand Down Expand Up @@ -497,7 +500,8 @@ type
BeaconBlockValidatorChanges* = object
# Collection of exits that are suitable for block production
proposer_slashings*: List[ProposerSlashing, Limit MAX_PROPOSER_SLASHINGS]
attester_slashings*: List[AttesterSlashing, Limit MAX_ATTESTER_SLASHINGS]
attester_slashings*:
List[phase0.AttesterSlashing, Limit MAX_ATTESTER_SLASHINGS]
voluntary_exits*: List[SignedVoluntaryExit, Limit MAX_VOLUNTARY_EXITS]
bls_to_execution_changes*:
List[SignedBLSToExecutionChange, Limit MAX_BLS_TO_EXECUTION_CHANGES]
Expand Down
9 changes: 6 additions & 3 deletions beacon_chain/spec/datatypes/deneb.nim
Original file line number Diff line number Diff line change
Expand Up @@ -393,7 +393,8 @@ type

# Operations
proposer_slashings*: List[ProposerSlashing, Limit MAX_PROPOSER_SLASHINGS]
attester_slashings*: List[AttesterSlashing, Limit MAX_ATTESTER_SLASHINGS]
attester_slashings*:
List[phase0.AttesterSlashing, Limit MAX_ATTESTER_SLASHINGS]
attestations*: List[Attestation, Limit MAX_ATTESTATIONS]
deposits*: List[Deposit, Limit MAX_DEPOSITS]
voluntary_exits*: List[SignedVoluntaryExit, Limit MAX_VOLUNTARY_EXITS]
Expand Down Expand Up @@ -428,7 +429,8 @@ type

# Operations
proposer_slashings*: List[TrustedProposerSlashing, Limit MAX_PROPOSER_SLASHINGS]
attester_slashings*: List[TrustedAttesterSlashing, Limit MAX_ATTESTER_SLASHINGS]
attester_slashings*:
List[phase0.TrustedAttesterSlashing, Limit MAX_ATTESTER_SLASHINGS]
attestations*: List[TrustedAttestation, Limit MAX_ATTESTATIONS]
deposits*: List[Deposit, Limit MAX_DEPOSITS]
voluntary_exits*: List[TrustedSignedVoluntaryExit, Limit MAX_VOLUNTARY_EXITS]
Expand All @@ -451,7 +453,8 @@ type

# Operations
proposer_slashings*: List[TrustedProposerSlashing, Limit MAX_PROPOSER_SLASHINGS]
attester_slashings*: List[TrustedAttesterSlashing, Limit MAX_ATTESTER_SLASHINGS]
attester_slashings*:
List[phase0.TrustedAttesterSlashing, Limit MAX_ATTESTER_SLASHINGS]
attestations*: List[TrustedAttestation, Limit MAX_ATTESTATIONS]
deposits*: List[Deposit, Limit MAX_DEPOSITS]
voluntary_exits*: List[TrustedSignedVoluntaryExit, Limit MAX_VOLUNTARY_EXITS]
Expand Down
11 changes: 6 additions & 5 deletions beacon_chain/spec/eth2_apis/eth2_rest_serialization.nim
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ createJsonFlavor RestJson
RestJson.useDefaultSerializationFor(
AggregateAndProof,
AttestationData,
AttesterSlashing,
BLSToExecutionChange,
BeaconBlockHeader,
BlobSidecar,
Expand Down Expand Up @@ -107,7 +106,6 @@ RestJson.useDefaultSerializationFor(
HistoricalSummary,
ImportDistributedKeystoresBody,
ImportRemoteKeystoresBody,
IndexedAttestation,
KeymanagerGenericError,
KeystoreInfo,
ListFeeRecipientResponse,
Expand Down Expand Up @@ -262,9 +260,11 @@ RestJson.useDefaultSerializationFor(
electra_mev.SignedBlindedBeaconBlock,
electra_mev.SignedBuilderBid,
phase0.Attestation,
phase0.AttesterSlashing,
phase0.BeaconBlock,
phase0.BeaconBlockBody,
phase0.BeaconState,
phase0.IndexedAttestation,
phase0.SignedBeaconBlock,
phase0.TrustedAttestation
)
Expand Down Expand Up @@ -323,7 +323,6 @@ const

type
EncodeTypes* =
AttesterSlashing |
BlobSidecarInfoObject |
DeleteKeystoresBody |
EmptyBody |
Expand All @@ -338,6 +337,7 @@ type
capella_mev.SignedBlindedBeaconBlock |
deneb_mev.SignedBlindedBeaconBlock |
electra_mev.SignedBlindedBeaconBlock |
phase0.AttesterSlashing |
SignedValidatorRegistrationV1 |
SignedVoluntaryExit |
Web3SignerRequest |
Expand Down Expand Up @@ -1709,7 +1709,7 @@ proc readValue*(reader: var JsonReader[RestJson],
proposer_slashings:
Opt[List[ProposerSlashing, Limit MAX_PROPOSER_SLASHINGS]]
attester_slashings:
Opt[List[AttesterSlashing, Limit MAX_ATTESTER_SLASHINGS]]
Opt[List[phase0.AttesterSlashing, Limit MAX_ATTESTER_SLASHINGS]]
attestations: Opt[List[phase0.Attestation, Limit MAX_ATTESTATIONS]]
deposits: Opt[List[Deposit, Limit MAX_DEPOSITS]]
voluntary_exits: Opt[List[SignedVoluntaryExit, Limit MAX_VOLUNTARY_EXITS]]
Expand Down Expand Up @@ -1748,7 +1748,8 @@ proc readValue*(reader: var JsonReader[RestJson],
"Multiple `attester_slashings` fields found",
"RestPublishedBeaconBlockBody")
attester_slashings = Opt.some(
reader.readValue(List[AttesterSlashing, Limit MAX_ATTESTER_SLASHINGS]))
reader.readValue(
List[phase0.AttesterSlashing, Limit MAX_ATTESTER_SLASHINGS]))
of "attestations":
if attestations.isSome():
reader.raiseUnexpectedField("Multiple `attestations` fields found",
Expand Down
3 changes: 2 additions & 1 deletion beacon_chain/spec/eth2_apis/rest_beacon_calls.nim
Original file line number Diff line number Diff line change
Expand Up @@ -332,7 +332,8 @@ proc getPoolAttesterSlashings*(): RestResponse[GetPoolAttesterSlashingsResponse]
meth: MethodGet.}
## https://ethereum.github.io/beacon-APIs/#/Beacon/getPoolAttesterSlashings

proc submitPoolAttesterSlashings*(body: AttesterSlashing): RestPlainResponse {.
proc submitPoolAttesterSlashings*(body: phase0.AttesterSlashing):
RestPlainResponse {.
rest, endpoint: "/eth/v1/beacon/pool/attester_slashings",
meth: MethodPost.}
## https://ethereum.github.io/beacon-APIs/#/Beacon/submitPoolAttesterSlashings
Expand Down
3 changes: 2 additions & 1 deletion beacon_chain/spec/eth2_apis/rest_types.nim
Original file line number Diff line number Diff line change
Expand Up @@ -554,7 +554,8 @@ type
GetPeerResponse* = DataMetaEnclosedObject[RestNodePeer]
GetPeersResponse* = DataMetaEnclosedObject[seq[RestNodePeer]]
GetPoolAttestationsResponse* = DataEnclosedObject[seq[phase0.Attestation]]
GetPoolAttesterSlashingsResponse* = DataEnclosedObject[seq[AttesterSlashing]]
GetPoolAttesterSlashingsResponse* =
DataEnclosedObject[seq[phase0.AttesterSlashing]]
GetPoolProposerSlashingsResponse* = DataEnclosedObject[seq[ProposerSlashing]]
GetPoolVoluntaryExitsResponse* = DataEnclosedObject[seq[SignedVoluntaryExit]]
GetProposerDutiesResponse* = DataRootEnclosedObject[seq[RestProposerDuty]]
Expand Down
2 changes: 1 addition & 1 deletion beacon_chain/validators/message_router.nim
Original file line number Diff line number Diff line change
Expand Up @@ -468,7 +468,7 @@ proc routeSignedVoluntaryExit*(
return ok()

proc routeAttesterSlashing*(
router: ref MessageRouter, slashing: AttesterSlashing):
router: ref MessageRouter, slashing: phase0.AttesterSlashing):
Future[SendResult] {.async: (raises: [CancelledError]).} =
block:
let res =
Expand Down
3 changes: 2 additions & 1 deletion beacon_chain/validators/validator_monitor.nim
Original file line number Diff line number Diff line change
Expand Up @@ -884,7 +884,8 @@ proc registerProposerSlashing*(
epochSummary.proposer_slashings += 1

proc registerAttesterSlashing*(
self: var ValidatorMonitor, src: MsgSource, slashing: AttesterSlashing) =
self: var ValidatorMonitor, src: MsgSource,
slashing: phase0.AttesterSlashing) =
let data = slashing.attestation_1.data

for idx in slashing.attestation_2.attesting_indices:
Expand Down
2 changes: 1 addition & 1 deletion ncli/ncli.nim
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ proc doSSZ(conf: NcliConf) =
printTimers(false, timers)

case kind
of "attester_slashing": printit(AttesterSlashing)
of "attester_slashing": printit(phase0.AttesterSlashing)
of "attestation": printit(phase0.Attestation)
of "phase0_signed_block": printit(phase0.SignedBeaconBlock)
of "altair_signed_block": printit(altair.SignedBeaconBlock)
Expand Down
2 changes: 1 addition & 1 deletion nfuzz/libnfuzz.nim
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ type
attestation: phase0.Attestation
AttesterSlashingInput = object
state: phase0.BeaconState
attesterSlashing: AttesterSlashing
attesterSlashing: phase0.AttesterSlashing
BlockInput = object
state: phase0.BeaconState
beaconBlock: phase0.SignedBeaconBlock
Expand Down
6 changes: 3 additions & 3 deletions tests/consensus_spec/altair/test_fixture_operations.nim
Original file line number Diff line number Diff line change
Expand Up @@ -91,16 +91,16 @@ suite baseDescription & "Attestation " & preset():

suite baseDescription & "Attester Slashing " & preset():
proc applyAttesterSlashing(
preState: var altair.BeaconState, attesterSlashing: AttesterSlashing):
Result[void, cstring] =
preState: var altair.BeaconState,
attesterSlashing: phase0.AttesterSlashing): Result[void, cstring] =
var cache: StateCache
doAssert (? process_attester_slashing(
defaultRuntimeConfig, preState, attesterSlashing, {strictVerification},
get_state_exit_queue_info(preState), cache))[0] > 0.Gwei
ok()

for path in walkTests(OpAttSlashingDir):
runTest[AttesterSlashing, typeof applyAttesterSlashing](
runTest[phase0.AttesterSlashing, typeof applyAttesterSlashing](
OpAttSlashingDir, suiteName, "Attester Slashing", "attester_slashing",
applyAttesterSlashing, path)

Expand Down
6 changes: 3 additions & 3 deletions tests/consensus_spec/bellatrix/test_fixture_operations.nim
Original file line number Diff line number Diff line change
Expand Up @@ -97,16 +97,16 @@ suite baseDescription & "Attestation " & preset():

suite baseDescription & "Attester Slashing " & preset():
proc applyAttesterSlashing(
preState: var bellatrix.BeaconState, attesterSlashing: AttesterSlashing):
Result[void, cstring] =
preState: var bellatrix.BeaconState,
attesterSlashing: phase0.AttesterSlashing): Result[void, cstring] =
var cache: StateCache
doAssert (? process_attester_slashing(
defaultRuntimeConfig, preState, attesterSlashing, {strictVerification},
get_state_exit_queue_info(preState), cache))[0] > 0.Gwei
ok()

for path in walkTests(OpAttSlashingDir):
runTest[AttesterSlashing, typeof applyAttesterSlashing](
runTest[phase0.AttesterSlashing, typeof applyAttesterSlashing](
OpAttSlashingDir, suiteName, "Attester Slashing", "attester_slashing",
applyAttesterSlashing, path)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ suite "EF - Bellatrix - SSZ consensus objects " & preset():
of "AggregateAndProof": checkSSZ(AggregateAndProof, path, hash)
of "Attestation": checkSSZ(Attestation, path, hash)
of "AttestationData": checkSSZ(AttestationData, path, hash)
of "AttesterSlashing": checkSSZ(AttesterSlashing, path, hash)
of "AttesterSlashing": checkSSZ(phase0.AttesterSlashing, path, hash)
of "BeaconBlock": checkSSZ(bellatrix.BeaconBlock, path, hash)
of "BeaconBlockBody": checkSSZ(bellatrix.BeaconBlockBody, path, hash)
of "BeaconBlockHeader": checkSSZ(BeaconBlockHeader, path, hash)
Expand All @@ -129,7 +129,8 @@ suite "EF - Bellatrix - SSZ consensus objects " & preset():
of "Fork": checkSSZ(Fork, path, hash)
of "ForkData": checkSSZ(ForkData, path, hash)
of "HistoricalBatch": checkSSZ(HistoricalBatch, path, hash)
of "IndexedAttestation": checkSSZ(IndexedAttestation, path, hash)
of "IndexedAttestation":
checkSSZ(phase0.IndexedAttestation, path, hash)
of "LightClientBootstrap":
checkSSZ(altair.LightClientBootstrap, path, hash)
of "LightClientHeader":
Expand Down Expand Up @@ -163,4 +164,4 @@ suite "EF - Bellatrix - SSZ consensus objects " & preset():
of "Validator": checkSSZ(Validator, path, hash)
of "VoluntaryExit": checkSSZ(VoluntaryExit, path, hash)
else:
raise newException(ValueError, "Unsupported test: " & sszType)
raise newException(ValueError, "Unsupported test: " & sszType)
Loading

0 comments on commit d139c92

Please sign in to comment.