[agent/codex:gpt-5.4-mini] Read docs/RFC.md fully. Find ONE feature described in the sp... #69
2 changed files with 70 additions and 0 deletions
12
service.go
12
service.go
|
|
@ -623,6 +623,9 @@ func (service *Service) replaceRecords(discovered map[string]NameRecords) {
|
|||
defer service.mu.Unlock()
|
||||
service.records = cached
|
||||
service.recordExpiry = expiry
|
||||
service.chainTreeRoot = ""
|
||||
service.lastTreeRootCheck = time.Time{}
|
||||
service.lastAliasFingerprint = ""
|
||||
service.refreshDerivedStateLocked()
|
||||
}
|
||||
|
||||
|
|
@ -646,6 +649,9 @@ func (service *Service) SetRecord(name string, record NameRecords) {
|
|||
} else if service.recordExpiry != nil {
|
||||
delete(service.recordExpiry, normalizedName)
|
||||
}
|
||||
service.chainTreeRoot = ""
|
||||
service.lastTreeRootCheck = time.Time{}
|
||||
service.lastAliasFingerprint = ""
|
||||
service.refreshDerivedStateLocked()
|
||||
}
|
||||
|
||||
|
|
@ -663,6 +669,9 @@ func (service *Service) RemoveRecord(name string) {
|
|||
if service.recordExpiry != nil {
|
||||
delete(service.recordExpiry, normalizedName)
|
||||
}
|
||||
service.chainTreeRoot = ""
|
||||
service.lastTreeRootCheck = time.Time{}
|
||||
service.lastAliasFingerprint = ""
|
||||
service.refreshDerivedStateLocked()
|
||||
}
|
||||
|
||||
|
|
@ -757,6 +766,9 @@ func (service *Service) pruneExpiredRecords() {
|
|||
}
|
||||
|
||||
if changed {
|
||||
service.chainTreeRoot = ""
|
||||
service.lastTreeRootCheck = time.Time{}
|
||||
service.lastAliasFingerprint = ""
|
||||
service.refreshDerivedStateLocked()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -396,6 +396,64 @@ func TestServiceHealthUsesChainTreeRootAfterDiscovery(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestServiceLocalMutationClearsChainTreeRoot(t *testing.T) {
|
||||
server := httptest.NewServer(http.HandlerFunc(func(responseWriter http.ResponseWriter, request *http.Request) {
|
||||
var payload struct {
|
||||
Method string `json:"method"`
|
||||
Params []any `json:"params"`
|
||||
}
|
||||
if err := json.NewDecoder(request.Body).Decode(&payload); err != nil {
|
||||
t.Fatalf("unexpected request payload: %v", err)
|
||||
}
|
||||
|
||||
switch payload.Method {
|
||||
case "getblockchaininfo":
|
||||
responseWriter.Header().Set("Content-Type", "application/json")
|
||||
_ = json.NewEncoder(responseWriter).Encode(map[string]any{
|
||||
"result": map[string]any{
|
||||
"tree_root": "chain-root-1",
|
||||
},
|
||||
})
|
||||
case "getnameresource":
|
||||
responseWriter.Header().Set("Content-Type", "application/json")
|
||||
_ = json.NewEncoder(responseWriter).Encode(map[string]any{
|
||||
"result": map[string]any{
|
||||
"a": []string{"10.10.10.10"},
|
||||
},
|
||||
})
|
||||
default:
|
||||
t.Fatalf("unexpected method: %s", payload.Method)
|
||||
}
|
||||
}))
|
||||
defer server.Close()
|
||||
|
||||
service := NewService(ServiceOptions{
|
||||
ChainAliasDiscoverer: func(_ context.Context) ([]string, error) {
|
||||
return []string{"gateway.charon.lthn"}, nil
|
||||
},
|
||||
HSDClient: NewHSDClient(HSDClientOptions{URL: server.URL}),
|
||||
})
|
||||
|
||||
if err := service.DiscoverAliases(context.Background()); err != nil {
|
||||
t.Fatalf("expected discovery to populate chain tree root: %v", err)
|
||||
}
|
||||
if health := service.Health(); health.TreeRoot != "chain-root-1" {
|
||||
t.Fatalf("expected chain tree root before local mutation, got %#v", health.TreeRoot)
|
||||
}
|
||||
|
||||
service.SetRecord("gateway.charon.lthn", NameRecords{
|
||||
A: []string{"10.10.10.11"},
|
||||
})
|
||||
|
||||
health := service.Health()
|
||||
if health.TreeRoot == "chain-root-1" {
|
||||
t.Fatalf("expected local mutation to clear stale chain tree root, got %#v", health.TreeRoot)
|
||||
}
|
||||
if health.TreeRoot == "" {
|
||||
t.Fatal("expected health to fall back to computed tree root after local mutation")
|
||||
}
|
||||
}
|
||||
|
||||
func TestServiceServeHTTPHealthReturnsJSON(t *testing.T) {
|
||||
service := NewService(ServiceOptions{
|
||||
Records: map[string]NameRecords{
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue