@@ -7,10 +7,11 @@ import (
77 "fmt"
88 "time"
99
10+ "github.com/ipfs/boxo/routing/http/internal/drjson"
1011 "github.com/ipfs/boxo/util"
1112 "github.com/ipfs/go-cid"
1213 "github.com/ipld/go-ipld-prime"
13- "github.com/ipld/go-ipld-prime/codec/dagjson "
14+ "github.com/ipld/go-ipld-prime/codec/dagcbor "
1415 "github.com/ipld/go-ipld-prime/datamodel"
1516 "github.com/ipld/go-ipld-prime/node/basicnode"
1617 "github.com/libp2p/go-libp2p/core/crypto"
@@ -51,9 +52,7 @@ type AnnouncementPayload struct {
5152 Metadata string
5253}
5354
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 ) {
5756 m := make (map [string ]ipld.Node )
5857 var err error
5958
@@ -112,29 +111,51 @@ func (ap AnnouncementPayload) MarshalJSON() ([]byte, error) {
112111 // Encode it with the DAG-JSON encoder, which automatically sorts the fields
113112 // in a deterministic manner.
114113 var b bytes.Buffer
115- err = dagjson .Encode (nd , & b )
114+ err = dagcbor .Encode (nd , & b )
116115 if err != nil {
117116 return nil , err
118117 }
119118
120119 return b .Bytes (), nil
121120}
122121
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+
123157func (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 {}
138159 err := json .Unmarshal (b , & v )
139160 if err != nil {
140161 return err
@@ -173,76 +194,20 @@ func (ap *AnnouncementPayload) UnmarshalJSON(b []byte) error {
173194
174195// AnnouncementRecord is a [Record] of [SchemaAnnouncement].
175196type 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"`
181201}
182202
183203func (ar * AnnouncementRecord ) GetSchema () string {
184204 return ar .Schema
185205}
186206
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-
232207func (ar AnnouncementRecord ) IsSigned () bool {
233208 return ar .Signature != ""
234209}
235210
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-
246211func (ar * AnnouncementRecord ) Sign (peerID peer.ID , key crypto.PrivKey ) error {
247212 if ar .IsSigned () {
248213 return errors .New ("already signed" )
@@ -260,13 +225,13 @@ func (ar *AnnouncementRecord) Sign(peerID peer.ID, key crypto.PrivKey) error {
260225 return errors .New ("not the correct signing key" )
261226 }
262227
263- err = ar .setRawPayload ()
228+ data , err : = ar .Payload . asDagCbor ()
264229 if err != nil {
265230 return err
266231 }
267232
268233 dataForSig := []byte (announcementSignaturePrefix )
269- dataForSig = append (dataForSig , ar . RawPayload ... )
234+ dataForSig = append (dataForSig , data ... )
270235
271236 rawSignature , err := key .Sign (dataForSig )
272237 if err != nil {
@@ -291,13 +256,9 @@ func (ar *AnnouncementRecord) Verify() error {
291256 return errors .New ("peer ID must be specified" )
292257 }
293258
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
301262 }
302263
303264 pk , err := ar .Payload .ID .ExtractPublicKey ()
@@ -311,7 +272,7 @@ func (ar *AnnouncementRecord) Verify() error {
311272 }
312273
313274 dataForSig := []byte (announcementSignaturePrefix )
314- dataForSig = append (dataForSig , ar . RawPayload ... )
275+ dataForSig = append (dataForSig , data ... )
315276
316277 ok , err := pk .Verify (dataForSig , sigBytes )
317278 if err != nil {
0 commit comments