-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathapi_mining_openapi_contract_test.go
More file actions
118 lines (106 loc) · 4.65 KB
/
Copy pathapi_mining_openapi_contract_test.go
File metadata and controls
118 lines (106 loc) · 4.65 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
package main
import (
"encoding/json"
"os"
"testing"
)
func TestOpenAPIMiningTemplateLeaseAndCompactSubmitContract(t *testing.T) {
specBytes, err := os.ReadFile("api_openapi.json")
if err != nil {
t.Fatalf("failed to read api_openapi.json: %v", err)
}
var spec map[string]any
if err := json.Unmarshal(specBytes, &spec); err != nil {
t.Fatalf("failed to parse api_openapi.json: %v", err)
}
components := mustGetMapAny(t, spec, "components")
schemas := mustGetMapAny(t, components, "schemas")
blockTemplate := mustGetMapAny(t, schemas, "BlockTemplate")
blockTemplateProps := mustGetMapAny(t, blockTemplate, "properties")
if _, ok := blockTemplateProps["template_id"]; !ok {
t.Fatal("BlockTemplate schema missing template_id")
}
if _, ok := blockTemplateProps["template_expires_at_unix_ms"]; !ok {
t.Fatal("BlockTemplate schema missing template_expires_at_unix_ms")
}
if _, ok := blockTemplateProps["mempool_generation"]; !ok {
t.Fatal("BlockTemplate schema missing mempool_generation")
}
renewRequest := mustGetMapAny(t, schemas, "RenewBlockTemplateRequest")
renewRequestProps := mustGetMapAny(t, renewRequest, "properties")
if _, ok := renewRequestProps["template_id"]; !ok {
t.Fatal("RenewBlockTemplateRequest missing template_id")
}
renewResponse := mustGetMapAny(t, schemas, "RenewBlockTemplateResponse")
renewResponseProps := mustGetMapAny(t, renewResponse, "properties")
if _, ok := renewResponseProps["template_expires_at_unix_ms"]; !ok {
t.Fatal("RenewBlockTemplateResponse missing template_expires_at_unix_ms")
}
compactSubmit := mustGetMapAny(t, schemas, "CompactSubmitBlock")
compactProps := mustGetMapAny(t, compactSubmit, "properties")
if _, ok := compactProps["template_id"]; !ok {
t.Fatal("CompactSubmitBlock missing template_id")
}
if _, ok := compactProps["nonce"]; !ok {
t.Fatal("CompactSubmitBlock missing nonce")
}
paths := mustGetMapAny(t, spec, "paths")
blockTemplatePath := mustGetMapAny(t, paths, "/api/mining/blocktemplate")
blockTemplateGet := mustGetMapAny(t, blockTemplatePath, "get")
blockTemplateResponses := mustGetMapAny(t, blockTemplateGet, "responses")
blockTemplateUnavailable := mustGetMapAny(t, blockTemplateResponses, "503")
unavailableContent := mustGetMapAny(t, blockTemplateUnavailable, "content")
unavailableJSON := mustGetMapAny(t, unavailableContent, "application/json")
unavailableExamples := mustGetMapAny(t, unavailableJSON, "examples")
leaseCapacity := mustGetMapAny(t, unavailableExamples, "lease_capacity")
leaseCapacityValue := mustGetMapAny(t, leaseCapacity, "value")
if got := leaseCapacityValue["code"]; got != "mining_template_cache_full" {
t.Fatalf("blocktemplate capacity code mismatch: got %#v", got)
}
tipChanged := mustGetMapAny(t, unavailableExamples, "tip_changed")
tipChangedValue := mustGetMapAny(t, tipChanged, "value")
if got := tipChangedValue["code"]; got != "mining_template_tip_changed" {
t.Fatalf("blocktemplate tip-change code mismatch: got %#v", got)
}
unavailableHeaders := mustGetMapAny(t, blockTemplateUnavailable, "headers")
if _, ok := unavailableHeaders["Retry-After"]; !ok {
t.Fatal("blocktemplate 503 contract missing Retry-After header")
}
renewPath := mustGetMapAny(t, paths, "/api/mining/renewtemplate")
renewPost := mustGetMapAny(t, renewPath, "post")
renewBody := mustGetMapAny(t, renewPost, "requestBody")
renewContent := mustGetMapAny(t, renewBody, "content")
renewJSON := mustGetMapAny(t, renewContent, "application/json")
renewSchema := mustGetMapAny(t, renewJSON, "schema")
if got := renewSchema["$ref"]; got != "#/components/schemas/RenewBlockTemplateRequest" {
t.Fatalf("renewtemplate request schema mismatch: got %#v", got)
}
renewResponses := mustGetMapAny(t, renewPost, "responses")
for _, status := range []string{"200", "400", "401", "404", "409"} {
if _, ok := renewResponses[status]; !ok {
t.Fatalf("renewtemplate responses missing status %s", status)
}
}
submitPath := mustGetMapAny(t, paths, "/api/mining/submitblock")
submitPost := mustGetMapAny(t, submitPath, "post")
requestBody := mustGetMapAny(t, submitPost, "requestBody")
content := mustGetMapAny(t, requestBody, "content")
appJSON := mustGetMapAny(t, content, "application/json")
reqSchema := mustGetMapAny(t, appJSON, "schema")
oneOf, ok := reqSchema["oneOf"].([]any)
if !ok || len(oneOf) != 2 {
t.Fatalf("submitblock request schema must be oneOf with 2 options, got %#v", reqSchema["oneOf"])
}
}
func mustGetMapAny(t *testing.T, m map[string]any, key string) map[string]any {
t.Helper()
raw, ok := m[key]
if !ok {
t.Fatalf("missing key %q in OpenAPI object", key)
}
out, ok := raw.(map[string]any)
if !ok {
t.Fatalf("key %q is not an object in OpenAPI", key)
}
return out
}