载入中...
搜索中...
未找到
SettlementReplay.cpp
浏览该文件的文档.
123void compareField(const T& expected, const T& actual, std::string path, std::vector<std::string>& differences) {
127eve::Result<const Value::Object*> strictObject(const Value& value, std::initializer_list<std::string_view> keys,
131 return failure<const Value::Object*>(eve::DiagnosticCode::TypeMismatch, "expected object", path);
142eve::Result<std::string> stringField(const Value::Object& object, std::string_view key, const std::string& path) {
159eve::Result<double> numberField(const Value::Object& object, std::string_view key, const std::string& path) {
164 return failure<double>(eve::DiagnosticCode::TypeMismatch, "expected number", path + "." + std::string(key));
171 return failure<std::uint64_t>(eve::DiagnosticCode::ParseError, "expected unsigned decimal text", path);
178 return failure<std::vector<std::string>>(eve::DiagnosticCode::TypeMismatch, "expected string array", path);
197 diagnostics.emplace_back(diagnostic.code(), diagnostic.severity(), diagnostic.message(), std::move(path),
205 value == "target_mitigation" || value == "armor_shield" || value == "clamp" || value == "apply" ||
269 auto chainObject = strictObject(object.at("chain"), {"depth", "emittedCount", "triggerPath"}, path + ".chain");
275 if (depth.value() < 0 || depth.value() > std::numeric_limits<std::uint32_t>::max() || emitted.value() < 0 ||
277 return failure<SettlementRequest>(eve::DiagnosticCode::InvalidArgument, "chain counter is out of range",
281 auto triggerPath = stringArray(chainObject.value()->at("triggerPath"), path + ".chain.triggerPath");
292 auto decisionObject = strictObject((*decisions)[index], {"accepted", "sample", "sequence", "stream",
309 return failure<SettlementRequest>(eve::DiagnosticCode::ParseError, "invalid decision stream id",
313 request.decisions.push_back({*stream, sequence.value(), sample.value(), threshold.value(), *accepted});
324 if (causationKind.value() == static_cast<std::int64_t>(game_event::CausationRef::Kind::Event)) {
326 if (!id) return failure<SettlementRequest>(eve::DiagnosticCode::ParseError, "invalid causation event id",
329 } else if (causationKind.value() == static_cast<std::int64_t>(game_event::CausationRef::Kind::Command)) {
331 if (!id) return failure<SettlementRequest>(eve::DiagnosticCode::ParseError, "invalid causation command id",
334 } else if (causationKind.value() != static_cast<std::int64_t>(game_event::CausationRef::Kind::None) ||
336 return failure<SettlementRequest>(eve::DiagnosticCode::InvalidArgument, "unsupported causation form",
339 if (correlationKind.value() == static_cast<std::int64_t>(game_event::CorrelationId::Kind::Id)) {
341 if (!id) return failure<SettlementRequest>(eve::DiagnosticCode::ParseError, "invalid correlation id",
344 } else if (correlationKind.value() != static_cast<std::int64_t>(game_event::CorrelationId::Kind::None) ||
346 return failure<SettlementRequest>(eve::DiagnosticCode::InvalidArgument, "unsupported correlation form",
356 if (!valid) return eve::Result<SettlementRequest>::failure(locateRequestStatus(valid.status(), path));
368 return failure<void>(eve::DiagnosticCode::InvalidArgument, "unexpected settlement result schema",
371 return failure<void>(eve::DiagnosticCode::UnknownVersion, "unsupported settlement result version",
383 return failure<void>(eve::DiagnosticCode::InvalidArgument, "expected finite non-negative number",
387 return failure<void>(eve::DiagnosticCode::TypeMismatch, "expected boolean", path + ".payload.critical");
399 return failure<void>(eve::DiagnosticCode::TypeMismatch, "expected stage array", path + ".payload.stages");
401 auto stage = strictObject((*stages)[index], {"after", "before", "details", "kind", "name", "status"},
434 auto request = decodeRequest((*derived)[index], path + ".payload.derived[" + std::to_string(index) + "]",
446 for (const auto field : {"causation", "correlation", "schema", "schemaVersion", "source", "subject",
482 auto checked = strictObject(root, {"request", "result", "resultDigest", "ruleDigest", "schema", "version"},
490 return failure<Value>(eve::DiagnosticCode::InvalidArgument, "unexpected replay schema", "record.schema");
492 return failure<Value>(eve::DiagnosticCode::UnknownVersion, "unsupported settlement replay version",
582 compareField(expected.stages[index].kind, actual.stages[index].kind, path + ".kind", differences);
583 compareField(expected.stages[index].name, actual.stages[index].name, path + ".name", differences);
584 compareField(expected.stages[index].status, actual.stages[index].status, path + ".status", differences);
585 compareField(expected.stages[index].before, actual.stages[index].before, path + ".before", differences);
586 compareField(expected.stages[index].after, actual.stages[index].after, path + ".after", differences);
587 compareField(expected.stages[index].details, actual.stages[index].details, path + ".details", differences);
594 if (!expectedEvent) return eve::Result<std::vector<std::string>>::failure(expectedEvent.status());
607 return eve::Result<std::vector<std::string>>::success(std::move(differences), eve::Status::success(code));
610eve::Result<std::string> createSettlementReplayRecord(const SettlementRequest& request, eve::ContentId ruleDigest,
656 if (!storedRuleText) return eve::Result<std::vector<std::string>>::failure(storedRuleText.status());
657 if (!storedResultText) return eve::Result<std::vector<std::string>>::failure(storedResultText.status());
661 return failure<std::vector<std::string>>(eve::DiagnosticCode::ParseError, "invalid rule digest",
664 return failure<std::vector<std::string>>(eve::DiagnosticCode::ParseError, "invalid result digest",
668 if (!expectedJson) return eve::Result<std::vector<std::string>>::failure(expectedJson.status());
670 if (!verifiedDigest) return eve::Result<std::vector<std::string>>::failure(verifiedDigest.status());
677 if (!encodedActual) return eve::Result<std::vector<std::string>>::failure(encodedActual.status());
682 return eve::Result<std::vector<std::string>>::success(std::move(differences), eve::Status::success(code));
static Diagnostic error(DiagnosticCode code, std::string message, std::string path={}, DiagnosticDetails details={}, std::string source={})
Construct an error diagnostic with the standard error severity.
Definition Diagnostic.h:125
static std::optional< LogicalId > parse(std::string_view text)
Parses a scoped logical name.
Definition Identity.cpp:36
static Result failure(Status status)
Construct a failed result from a structured status.
Definition Result.h:175
static Status success(StatusCode code=StatusCode::Ok)
Construct a successful status with an explicit non-error outcome.
Definition Status.h:81
static SubjectRef fromPersistentId(PersistentId id) noexcept
Wrap a persistent identity without changing its bytes.
Definition SubjectRef.h:32
static Result< Value > fromJson(std::string_view json)
Parse one strict JSON value into an owning Value.
Definition Value.cpp:57
std::string format() const
Formats the ID in lower-case canonical UUID text.
Definition Identity.h:173
constexpr bool isNil() const noexcept
Returns whether this value is the all-zero nil ID.
Definition Identity.h:176
static std::optional< Id128 > parse(std::string_view text) noexcept
Parses canonical UUID text.
Definition Identity.h:151
static CausationRef fromEventId(EventId value)
Creates a causation reference to an event.
Definition GameEvent.h:105
static CausationRef fromCommandId(CommandId value)
Creates a causation reference to a command.
Definition GameEvent.h:115
static CorrelationId fromEventId(EventId value)
Creates a canonical correlation ID from an EventId.
Definition GameEvent.h:58
std::variant< std::monostate, std::int64_t, double, std::string, bool > Value
Definition Database.h:26
const EditorValue * field(const EditorValue &value, const char *name)
Definition RoadNetworkEditTarget.cpp:15
Definition Settlement.cpp:10
const char * settlementDispositionName(SettlementDisposition disposition) noexcept
Return the stable lowercase spelling of a settlement disposition.
Definition Settlement.cpp:256
EVENGINE_API_FOUNDATION eve::Result< SettlementRequest > settlementReplayRequest(std::string_view recordJson)
Decode the request from a strict version-1 replay record.
Definition SettlementReplay.cpp:636
EVENGINE_API_FOUNDATION eve::Result< std::vector< std::string > > verifySettlementResult(const SettlementResult &expected, const SettlementResult &actual)
Compare two settlement results and report stable field paths that differ.
Definition SettlementReplay.cpp:566
const char * stageKindName(StageKind kind) noexcept
Return the stable lowercase spelling of a stage kind.
Definition Settlement.cpp:241
SettlementTraceLevel
Amount of stage explanation retained by one settlement request.
Definition Settlement.h:60
EVENGINE_API_FOUNDATION eve::Result< std::string > createSettlementReplayRecord(const SettlementRequest &request, eve::ContentId ruleDigest, const SettlementResult &result, const eve::SnapshotHashProvider &hashProvider)
Serialize one replayable request with its rule and expected-result identities.
Definition SettlementReplay.cpp:610
eve::Result< void > validateSettlementRequest(const SettlementRequest &request)
Validate the canonical semantic invariants of a settlement request.
Definition Settlement.cpp:40
EVENGINE_API_FOUNDATION eve::Result< std::string > settlementResultCanonicalJson(const SettlementResult &result)
Serialize the stable semantic fields of a settlement result as canonical JSON.
Definition SettlementReplay.cpp:550
EVENGINE_API_FOUNDATION eve::Result< std::vector< std::string > > verifySettlementReplayRecord(std::string_view recordJson, eve::ContentId ruleDigest, const SettlementResult &actual, const eve::SnapshotHashProvider &hashProvider)
Verify current rules and outcome against a strict replay record.
Definition SettlementReplay.cpp:643
EVENGINE_API_FOUNDATION eve::Result< eve::ContentId > settlementResultDigest(const SettlementResult &result, const eve::SnapshotHashProvider &hashProvider)
Hash the canonical semantic representation of a settlement result.
Definition SettlementReplay.cpp:556
@ HashMismatch
@ InvalidArgument
@ TypeMismatch
A stable reference resolved to a different canonical domain type.
@ UnknownVersion
@ PreconditionViolation
@ ParseError
@ NoOp
@ Applied
@ Failed
@ Object
detail::StrongUint64< detail::SimulationTickTag > SimulationTick
Deterministic simulation time step; it is not wall-clock time.
Definition Time.h:31
std::function< Result< ContentId >(std::string_view canonicalInput)> SnapshotHashProvider
Injected content-digest implementation used by snapshots.
Definition Snapshot.h:36
Definition Container.h:602
Domain-neutral, deterministic settlement pipeline.
Domain-neutral input to one settlement operation.
Definition Settlement.h:107
Complete observable outcome of one successful settlement.
Definition Settlement.h:163
std::vector< SettlementRequest > derived
Owning derived requests emitted by the policy in deterministic order.
Definition Settlement.h:175
std::vector< SettlementStageResult > stages
Definition Settlement.h:172
std::optional< game_event::GameEvent > event
Definition Settlement.h:173
SettlementDisposition disposition
Definition Settlement.h:170