@@ -7,10 +7,11 @@ import (
7
7
"fmt"
8
8
"time"
9
9
10
+ "github.com/ipfs/boxo/routing/http/internal/drjson"
10
11
"github.com/ipfs/boxo/util"
11
12
"github.com/ipfs/go-cid"
12
13
"github.com/ipld/go-ipld-prime"
13
- "github.com/ipld/go-ipld-prime/codec/dagjson "
14
+ "github.com/ipld/go-ipld-prime/codec/dagcbor "
14
15
"github.com/ipld/go-ipld-prime/datamodel"
15
16
"github.com/ipld/go-ipld-prime/node/basicnode"
16
17
"github.com/libp2p/go-libp2p/core/crypto"
@@ -51,9 +52,7 @@ type AnnouncementPayload struct {
51
52
Metadata string
52
53
}
53
54
54
- // MarshalJSON marshals the [AnnouncementPayload] into a canonical DAG-JSON
55
- // representation of the payload.
56
- func (ap AnnouncementPayload ) MarshalJSON () ([]byte , error ) {
55
+ func (ap AnnouncementPayload ) asDagCbor () ([]byte , error ) {
57
56
m := make (map [string ]ipld.Node )
58
57
var err error
59
58
@@ -112,29 +111,51 @@ func (ap AnnouncementPayload) MarshalJSON() ([]byte, error) {
112
111
// Encode it with the DAG-JSON encoder, which automatically sorts the fields
113
112
// in a deterministic manner.
114
113
var b bytes.Buffer
115
- err = dagjson .Encode (nd , & b )
114
+ err = dagcbor .Encode (nd , & b )
116
115
if err != nil {
117
116
return nil , err
118
117
}
119
118
120
119
return b .Bytes (), nil
121
120
}
122
121
122
+ type announcementPayloadHelper struct {
123
+ CID string `json:",omitempty"`
124
+ ID * peer.ID `json:",omitempty"`
125
+ Scope AnnouncementScope `json:",omitempty"`
126
+ Timestamp string `json:",omitempty"`
127
+ TTL int64 `json:",omitempty"`
128
+ Addrs []Multiaddr `json:",omitempty"`
129
+ Protocols []string `json:",omitempty"`
130
+ Metadata string `json:",omitempty"`
131
+ }
132
+
133
+ func (ap AnnouncementPayload ) MarshalJSON () ([]byte , error ) {
134
+ v := announcementPayloadHelper {
135
+ ID : ap .ID ,
136
+ Scope : ap .Scope ,
137
+ Addrs : ap .Addrs ,
138
+ Protocols : ap .Protocols ,
139
+ Metadata : ap .Metadata ,
140
+ }
141
+
142
+ if ap .CID .Defined () {
143
+ v .CID = ap .CID .String ()
144
+ }
145
+
146
+ if ! ap .Timestamp .IsZero () {
147
+ v .Timestamp = util .FormatRFC3339 (ap .Timestamp )
148
+ }
149
+
150
+ if ap .TTL != 0 {
151
+ v .TTL = ap .TTL .Milliseconds ()
152
+ }
153
+
154
+ return drjson .MarshalJSONBytes (v )
155
+ }
156
+
123
157
func (ap * AnnouncementPayload ) UnmarshalJSON (b []byte ) error {
124
- // TODO: this is the "simple" way of decoding the payload. I am assuming
125
- // we want to encode everything using strings (except for TTL). If we decide
126
- // to use DAG-JSON native types (e.g. Bytes), we have to convert this to IPLD code
127
- // in order to convert things properly.
128
- v := struct {
129
- CID string
130
- Scope AnnouncementScope
131
- Timestamp string
132
- TTL int64
133
- ID * peer.ID
134
- Addrs []Multiaddr
135
- Protocols []string
136
- Metadata string
137
- }{}
158
+ v := announcementPayloadHelper {}
138
159
err := json .Unmarshal (b , & v )
139
160
if err != nil {
140
161
return err
@@ -173,76 +194,20 @@ func (ap *AnnouncementPayload) UnmarshalJSON(b []byte) error {
173
194
174
195
// AnnouncementRecord is a [Record] of [SchemaAnnouncement].
175
196
type AnnouncementRecord struct {
176
- Schema string
177
- Error string
178
- Payload AnnouncementPayload
179
- RawPayload json.RawMessage
180
- Signature string
197
+ Schema string
198
+ Error string `json:",omitempty"`
199
+ Payload AnnouncementPayload
200
+ Signature string `json:",omitempty"`
181
201
}
182
202
183
203
func (ar * AnnouncementRecord ) GetSchema () string {
184
204
return ar .Schema
185
205
}
186
206
187
- func (ar AnnouncementRecord ) MarshalJSON () ([]byte , error ) {
188
- if ar .RawPayload == nil {
189
- // This happens when [AnnouncementRecord] is used for response. In that
190
- // case it is not signed. Therefore, the RawPayload is not yet set.
191
- err := ar .setRawPayload ()
192
- if err != nil {
193
- return nil , err
194
- }
195
- }
196
-
197
- v := struct {
198
- Schema string
199
- Error string `json:"Error,omitempty"`
200
- Payload json.RawMessage
201
- Signature string `json:"Signature,omitempty"`
202
- }{
203
- Schema : ar .Schema ,
204
- Error : ar .Error ,
205
- Payload : ar .RawPayload ,
206
- Signature : ar .Signature ,
207
- }
208
-
209
- return json .Marshal (v )
210
- }
211
-
212
- func (ar * AnnouncementRecord ) UnmarshalJSON (b []byte ) error {
213
- // Unmarshal all known fields and assign them.
214
- v := struct {
215
- Schema string
216
- Error string
217
- Payload json.RawMessage
218
- Signature string
219
- }{}
220
- err := json .Unmarshal (b , & v )
221
- if err != nil {
222
- return err
223
- }
224
-
225
- ar .Schema = v .Schema
226
- ar .Error = v .Error
227
- ar .RawPayload = v .Payload
228
- ar .Signature = v .Signature
229
- return (& ar .Payload ).UnmarshalJSON (ar .RawPayload )
230
- }
231
-
232
207
func (ar AnnouncementRecord ) IsSigned () bool {
233
208
return ar .Signature != ""
234
209
}
235
210
236
- func (ar * AnnouncementRecord ) setRawPayload () error {
237
- bytes , err := ar .Payload .MarshalJSON ()
238
- if err != nil {
239
- return err
240
- }
241
-
242
- ar .RawPayload = bytes
243
- return nil
244
- }
245
-
246
211
func (ar * AnnouncementRecord ) Sign (peerID peer.ID , key crypto.PrivKey ) error {
247
212
if ar .IsSigned () {
248
213
return errors .New ("already signed" )
@@ -260,13 +225,13 @@ func (ar *AnnouncementRecord) Sign(peerID peer.ID, key crypto.PrivKey) error {
260
225
return errors .New ("not the correct signing key" )
261
226
}
262
227
263
- err = ar .setRawPayload ()
228
+ data , err : = ar .Payload . asDagCbor ()
264
229
if err != nil {
265
230
return err
266
231
}
267
232
268
233
dataForSig := []byte (announcementSignaturePrefix )
269
- dataForSig = append (dataForSig , ar . RawPayload ... )
234
+ dataForSig = append (dataForSig , data ... )
270
235
271
236
rawSignature , err := key .Sign (dataForSig )
272
237
if err != nil {
@@ -291,13 +256,9 @@ func (ar *AnnouncementRecord) Verify() error {
291
256
return errors .New ("peer ID must be specified" )
292
257
}
293
258
294
- // note that we only generate and set the payload if it hasn't already been set
295
- // to allow for passing through the payload untouched if it is already provided
296
- if ar .RawPayload == nil {
297
- err := ar .setRawPayload ()
298
- if err != nil {
299
- return err
300
- }
259
+ data , err := ar .Payload .asDagCbor ()
260
+ if err != nil {
261
+ return err
301
262
}
302
263
303
264
pk , err := ar .Payload .ID .ExtractPublicKey ()
@@ -311,7 +272,7 @@ func (ar *AnnouncementRecord) Verify() error {
311
272
}
312
273
313
274
dataForSig := []byte (announcementSignaturePrefix )
314
- dataForSig = append (dataForSig , ar . RawPayload ... )
275
+ dataForSig = append (dataForSig , data ... )
315
276
316
277
ok , err := pk .Verify (dataForSig , sigBytes )
317
278
if err != nil {
0 commit comments