diff --git a/ncli/resttest-rules.json b/ncli/resttest-rules.json index ac3396e11..aef11baa9 100644 --- a/ncli/resttest-rules.json +++ b/ncli/resttest-rules.json @@ -1973,7 +1973,10 @@ }, "response": { "status": {"operator": "equals", "value": "200"}, - "headers": [{"key": "Content-Type", "value": "application/json", "operator": "equals"}], + "headers": [ + {"key": "Content-Type", "value": "application/json", "operator": "equals"}, + {"key": "Eth-Consensus-Version", "value": ["phase0", "altair", "bellatrix"], "operator": "oneof"} + ], "body": [{"operator": "jstructcmpns", "value": {"version": "", "data": {"message": {"slot": "", "proposer_index": "", "parent_root": "", "state_root": "", "body": {"randao_reveal": "", "eth1_data": {"deposit_root": "", "deposit_count": "", "block_hash": ""}, "graffiti": "", "proposer_slashings": [{"signed_header_1": {"message": {"slot": "", "proposer_index": "", "parent_root": "", "state_root": "", "body_root": ""},"signature": ""}, "signed_header_2": {"message": {"slot": "", "proposer_index": "", "parent_root": "", "state_root": "", "body_root": ""},"signature": ""}}], "attester_slashings": [{"attestation_1": {"attesting_indices": [""], "signature": "", "data": {"slot": "", "index": "", "beacon_block_root": "", "source": {"epoch": "", "root": ""}, "target": {"epoch": "", "root": ""}}}, "attestation_2": {"attesting_indices": [""], "signature": "", "data": {"slot": "", "index": "", "beacon_block_root": "", "source": {"epoch": "", "root": ""}, "target": {"epoch": "", "root": ""}}}}], "attestations": [{"aggregation_bits": "", "signature": "", "data": {"slot": "", "index": "", "beacon_block_root": "", "source": {"epoch": "", "root": ""}, "target": {"epoch": "", "root": ""}}}], "deposits": [{"proof": [""], "data": {"pubkey": "", "withdrawal_credentials": "", "amount": "", "signature": ""}}], "voluntary_exits": [{"message": {"epoch": "", "validator_index": ""}, "signature": ""}]}}, "signature": ""}}}] } }, @@ -1985,7 +1988,10 @@ }, "response": { "status": {"operator": "equals", "value": "200"}, - "headers": [{"key": "Content-Type", "value": "application/json", "operator": "equals"}], + "headers": [ + {"key": "Content-Type", "value": "application/json", "operator": "equals"}, + {"key": "Eth-Consensus-Version", "value": ["phase0", "altair", "bellatrix"], "operator": "oneof"} + ], "body": [{"operator": "jstructcmpns", "value": {"version": "", "data": {"message": {"slot": "", "proposer_index": "", "parent_root": "", "state_root": "", "body": {"randao_reveal": "", "eth1_data": {"deposit_root": "", "deposit_count": "", "block_hash": ""}, "graffiti": "", "proposer_slashings": [{"signed_header_1": {"message": {"slot": "", "proposer_index": "", "parent_root": "", "state_root": "", "body_root": ""},"signature": ""}, "signed_header_2": {"message": {"slot": "", "proposer_index": "", "parent_root": "", "state_root": "", "body_root": ""},"signature": ""}}], "attester_slashings": [{"attestation_1": {"attesting_indices": [""], "signature": "", "data": {"slot": "", "index": "", "beacon_block_root": "", "source": {"epoch": "", "root": ""}, "target": {"epoch": "", "root": ""}}}, "attestation_2": {"attesting_indices": [""], "signature": "", "data": {"slot": "", "index": "", "beacon_block_root": "", "source": {"epoch": "", "root": ""}, "target": {"epoch": "", "root": ""}}}}], "attestations": [{"aggregation_bits": "", "signature": "", "data": {"slot": "", "index": "", "beacon_block_root": "", "source": {"epoch": "", "root": ""}, "target": {"epoch": "", "root": ""}}}], "deposits": [{"proof": [""], "data": {"pubkey": "", "withdrawal_credentials": "", "amount": "", "signature": ""}}], "voluntary_exits": [{"message": {"epoch": "", "validator_index": ""}, "signature": ""}]}}, "signature": ""}}}] } }, @@ -1997,7 +2003,10 @@ }, "response": { "status": {"operator": "equals", "value": "200"}, - "headers": [{"key": "Content-Type", "value": "application/json", "operator": "equals"}], + "headers": [ + {"key": "Content-Type", "value": "application/json", "operator": "equals"}, + {"key": "Eth-Consensus-Version", "value": ["phase0", "altair", "bellatrix"], "operator": "oneof"} + ], "body": [{"operator": "jstructcmpns", "value": {"version": "", "data": {"message": {"slot": "", "proposer_index": "", "parent_root": "", "state_root": "", "body": {"randao_reveal": "", "eth1_data": {"deposit_root": "", "deposit_count": "", "block_hash": ""}, "graffiti": "", "proposer_slashings": [{"signed_header_1": {"message": {"slot": "", "proposer_index": "", "parent_root": "", "state_root": "", "body_root": ""},"signature": ""}, "signed_header_2": {"message": {"slot": "", "proposer_index": "", "parent_root": "", "state_root": "", "body_root": ""},"signature": ""}}], "attester_slashings": [{"attestation_1": {"attesting_indices": [""], "signature": "", "data": {"slot": "", "index": "", "beacon_block_root": "", "source": {"epoch": "", "root": ""}, "target": {"epoch": "", "root": ""}}}, "attestation_2": {"attesting_indices": [""], "signature": "", "data": {"slot": "", "index": "", "beacon_block_root": "", "source": {"epoch": "", "root": ""}, "target": {"epoch": "", "root": ""}}}}], "attestations": [{"aggregation_bits": "", "signature": "", "data": {"slot": "", "index": "", "beacon_block_root": "", "source": {"epoch": "", "root": ""}, "target": {"epoch": "", "root": ""}}}], "deposits": [{"proof": [""], "data": {"pubkey": "", "withdrawal_credentials": "", "amount": "", "signature": ""}}], "voluntary_exits": [{"message": {"epoch": "", "validator_index": ""}, "signature": ""}]}}, "signature": ""}}}] } }, @@ -2009,7 +2018,10 @@ }, "response": { "status": {"operator": "equals", "value": "200"}, - "headers": [{"key": "Content-Type", "value": "application/json", "operator": "equals"}], + "headers": [ + {"key": "Content-Type", "value": "application/json", "operator": "equals"}, + {"key": "Eth-Consensus-Version", "value": ["phase0", "altair", "bellatrix"], "operator": "oneof"} + ], "body": [{"operator": "jstructcmpns", "value": {"version": "", "data": {"message": {"slot": "", "proposer_index": "", "parent_root": "", "state_root": "", "body": {"randao_reveal": "", "eth1_data": {"deposit_root": "", "deposit_count": "", "block_hash": ""}, "graffiti": "", "proposer_slashings": [{"signed_header_1": {"message": {"slot": "", "proposer_index": "", "parent_root": "", "state_root": "", "body_root": ""},"signature": ""}, "signed_header_2": {"message": {"slot": "", "proposer_index": "", "parent_root": "", "state_root": "", "body_root": ""},"signature": ""}}], "attester_slashings": [{"attestation_1": {"attesting_indices": [""], "signature": "", "data": {"slot": "", "index": "", "beacon_block_root": "", "source": {"epoch": "", "root": ""}, "target": {"epoch": "", "root": ""}}}, "attestation_2": {"attesting_indices": [""], "signature": "", "data": {"slot": "", "index": "", "beacon_block_root": "", "source": {"epoch": "", "root": ""}, "target": {"epoch": "", "root": ""}}}}], "attestations": [{"aggregation_bits": "", "signature": "", "data": {"slot": "", "index": "", "beacon_block_root": "", "source": {"epoch": "", "root": ""}, "target": {"epoch": "", "root": ""}}}], "deposits": [{"proof": [""], "data": {"pubkey": "", "withdrawal_credentials": "", "amount": "", "signature": ""}}], "voluntary_exits": [{"message": {"epoch": "", "validator_index": ""}, "signature": ""}]}}, "signature": ""}}}] } }, @@ -2021,7 +2033,10 @@ }, "response": { "status": {"operator": "equals", "value": "404"}, - "headers": [{"key": "Content-Type", "value": "application/json", "operator": "equals"}], + "headers": [ + {"key": "Content-Type", "value": "application/json", "operator": "equals"}, + {"key": "Eth-Consensus-Version", "operator": "notexists"} + ], "body": [{"operator": "jstructcmpns", "value": {"code": "", "message": ""}}] } }, @@ -2033,7 +2048,10 @@ }, "response": { "status": {"operator": "equals", "value": "400"}, - "headers": [{"key": "Content-Type", "value": "application/json", "operator": "equals"}], + "headers": [ + {"key": "Content-Type", "value": "application/json", "operator": "equals"}, + {"key": "Eth-Consensus-Version", "operator": "notexists"} + ], "body": [{"operator": "jstructcmpns", "value": {"code": "", "message": ""}}] } }, @@ -2045,7 +2063,10 @@ }, "response": { "status": {"operator": "equals", "value": "404"}, - "headers": [{"key": "Content-Type", "value": "application/json", "operator": "equals"}], + "headers": [ + {"key": "Content-Type", "value": "application/json", "operator": "equals"}, + {"key": "Eth-Consensus-Version", "operator": "notexists"} + ], "body": [{"operator": "jstructcmpns", "value": {"code": "", "message": ""}}] } }, @@ -2057,7 +2078,10 @@ }, "response": { "status": {"operator": "equals", "value": "400"}, - "headers": [{"key": "Content-Type", "value": "application/json", "operator": "equals"}], + "headers": [ + {"key": "Content-Type", "value": "application/json", "operator": "equals"}, + {"key": "Eth-Consensus-Version", "operator": "notexists"} + ], "body": [{"operator": "jstructcmpns", "value": {"code": "", "message": ""}}] } }, @@ -2685,6 +2709,21 @@ "body": [{"operator": "jstructcmps", "start": ["data"], "value": {"genesis_time": "", "genesis_validators_root": "", "slot": "", "fork": {"previous_version": "", "current_version": "", "epoch": ""}, "latest_block_header": {"slot": "", "proposer_index": "", "parent_root": "", "state_root": "", "body_root": ""}, "block_roots": [""], "state_roots": [""], "historical_roots": [""], "eth1_data": {"deposit_root": "", "deposit_count": "", "block_hash": ""}, "eth1_data_votes": [{"deposit_root": "", "deposit_count": "", "block_hash": ""}], "eth1_deposit_index": "", "validators": [{"pubkey": "", "withdrawal_credentials": "", "effective_balance": "", "slashed": false, "activation_eligibility_epoch": "", "activation_epoch": "", "exit_epoch": "", "withdrawable_epoch": ""}], "balances": [""], "randao_mixes": [""], "slashings": [""], "previous_epoch_attestations": [{"aggregation_bits": "", "data": {"slot": "", "index": "", "beacon_block_root": "", "source": {"epoch": "", "root": ""}, "target": {"epoch": "", "root": ""}}, "inclusion_delay": "", "proposer_index": ""}], "current_epoch_attestations": [{"aggregation_bits": "", "data": {"slot": "", "index": "", "beacon_block_root": "", "source": {"epoch": "", "root": ""}, "target": {"epoch": "", "root": ""}}, "inclusion_delay": "", "proposer_index": ""}], "justification_bits": "", "previous_justified_checkpoint": {"epoch": "", "root": ""}, "current_justified_checkpoint": {"epoch": "", "root": ""}, "finalized_checkpoint": {"epoch": "", "root": ""}}}] } }, + { + "topics": ["debug", "beacon_states_head_slow", "slow"], + "request": { + "url": "/eth/v2/debug/beacon/states/head", + "headers": {"Accept": "application/json"} + }, + "response": { + "status": {"operator": "equals", "value": "200"}, + "headers": [ + {"key": "Content-Type", "value": "application/json", "operator": "equals"}, + {"key": "Eth-Consensus-Version", "value": ["phase0", "altair", "bellatrix"], "operator": "oneof"} + ], + "body": [{"operator": "jstructcmps", "start": ["data"], "value": {"genesis_time": "", "genesis_validators_root": "", "slot": "", "fork": {"previous_version": "", "current_version": "", "epoch": ""}, "latest_block_header": {"slot": "", "proposer_index": "", "parent_root": "", "state_root": "", "body_root": ""}, "block_roots": [""], "state_roots": [""], "historical_roots": [""], "eth1_data": {"deposit_root": "", "deposit_count": "", "block_hash": ""}, "eth1_data_votes": [{"deposit_root": "", "deposit_count": "", "block_hash": ""}], "eth1_deposit_index": "", "validators": [{"pubkey": "", "withdrawal_credentials": "", "effective_balance": "", "slashed": false, "activation_eligibility_epoch": "", "activation_epoch": "", "exit_epoch": "", "withdrawable_epoch": ""}], "balances": [""], "randao_mixes": [""], "slashings": [""], "previous_epoch_attestations": [{"aggregation_bits": "", "data": {"slot": "", "index": "", "beacon_block_root": "", "source": {"epoch": "", "root": ""}, "target": {"epoch": "", "root": ""}}, "inclusion_delay": "", "proposer_index": ""}], "current_epoch_attestations": [{"aggregation_bits": "", "data": {"slot": "", "index": "", "beacon_block_root": "", "source": {"epoch": "", "root": ""}, "target": {"epoch": "", "root": ""}}, "inclusion_delay": "", "proposer_index": ""}], "justification_bits": "", "previous_justified_checkpoint": {"epoch": "", "root": ""}, "current_justified_checkpoint": {"epoch": "", "root": ""}, "finalized_checkpoint": {"epoch": "", "root": ""}}}] + } + }, { "topics": ["node"], "request": { diff --git a/ncli/resttest.nim b/ncli/resttest.nim index e2610e0a1..8ad0bdbc4 100644 --- a/ncli/resttest.nim +++ b/ncli/resttest.nim @@ -1,3 +1,10 @@ +# beacon_chain +# Copyright (c) 2021-2022 Status Research & Development GmbH +# Licensed and distributed under either of +# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT). +# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0). +# at your option. This file may not be copied, modified, or distributed except according to those terms. + import std/[strutils, os, options, uri, json, tables] import stew/[results, io2, base10] import confutils, chronicles, httputils, @@ -24,7 +31,7 @@ type Equals, OneOf, Inside, InsideOrEq HeaderOperatorKind {.pure.} = enum - Exists, Equals, OneOf, Substr + Exists, NotExists, Equals, OneOf, Substr BodyOperatorKind {.pure.} = enum Exists, JsonStructCmpS, JsonStructCmpNS @@ -574,6 +581,8 @@ proc getResponseHeadersExpect(rule: JsonNode): Result[HeadersExpect, cstring] = case toLowerAscii(jop.str) of "exists": HeaderOperatorKind.Exists + of "notexists": + HeaderOperatorKind.NotExists of "equals": HeaderOperatorKind.Equals of "oneof": @@ -586,24 +595,25 @@ proc getResponseHeadersExpect(rule: JsonNode): Result[HeadersExpect, cstring] = block: var vres: seq[string] let jvalue = jitem.getOrDefault("value") - case jvalue.kind - of JArray: - if len(jvalue.elems) == 0: - return err("`response.header` element has an empty array value") - for jelem in jvalue.elems: - case jelem.kind - of JString: - vres.add(jvalue.str) - of JInt: - vres.add(Base10.toString(uint64(jvalue.num))) - else: - return err("`response.header` element has incorrect value") - of JString: - vres.add(jvalue.str) - of JInt: - vres.add(Base10.toString(uint64(jvalue.num))) - else: - return err("`response.header` element has incorrect value") + if not isnil(jvalue): + case jvalue.kind + of JArray: + if len(jvalue.elems) == 0: + return err("`response.header` element has an empty array value") + for jelem in jvalue.elems: + case jelem.kind + of JString: + vres.add(jelem.str) + of JInt: + vres.add(Base10.toString(uint64(jvalue.num))) + else: + return err("`response.header` element has incorrect value") + of JString: + vres.add(jvalue.str) + of JInt: + vres.add(Base10.toString(uint64(jvalue.num))) + else: + return err("`response.header` element has incorrect value") vres res.add(HeaderExpect(key: key, value: value, kind: operator)) ok(HeadersExpect(headers: res)) @@ -704,6 +714,9 @@ proc validateHeaders(resp: HttpResponseHeader, expect: HeadersExpect): bool = of HeaderOperatorKind.Exists: if item.key notin resp: return false + of HeaderOperatorKind.NotExists: + if item.key in resp: + return false of HeaderOperatorKind.Equals: if item.key notin resp: return false