@@ -17,22 +17,32 @@ import (
1717 "github.com/hyperledger-labs/fabric-token-sdk/token/token"
1818)
1919
20- // Metadata contains the metadata of a Token Request
20+ // Metadata contains the metadata of a Token Request.
21+ // This metadata is used to unscramble the content of the actions in the Token Request.
22+ // It includes information about issuers, owners, and extra signers.
2123type Metadata struct {
22- TokenService driver.TokensService
23- WalletService driver.WalletService
24+ // TokenService is the service used to handle tokens.
25+ TokenService driver.TokensService
26+ // WalletService is the service used to handle wallets and identities.
27+ WalletService driver.WalletService
28+ // TokenRequestMetadata contains the metadata of the Token Request as defined by the driver.
2429 TokenRequestMetadata * driver.TokenRequestMetadata
25- Logger logging.Logger
30+ // Logger is the logger used by this struct.
31+ Logger logging.Logger
2632}
2733
2834// SpentTokenID returns the token IDs of the tokens that were spent by the Token Request this metadata is associated with.
35+ // It iterates over all issue and transfer actions and collects the IDs of the input tokens.
2936func (m * Metadata ) SpentTokenID () []* token.ID {
3037 var res []* token.ID
38+ // Collect token IDs from issue actions.
39+ // Note: issue actions usually don't have inputs, but some drivers might use them (e.g., for token upgrades).
3140 for _ , issue := range m .TokenRequestMetadata .Issues {
3241 for _ , input := range issue .Inputs {
3342 res = append (res , input .TokenID )
3443 }
3544 }
45+ // Collect token IDs from transfer actions.
3646 for _ , transfer := range m .TokenRequestMetadata .Transfers {
3747 for _ , input := range transfer .Inputs {
3848 res = append (res , input .TokenID )
@@ -43,25 +53,30 @@ func (m *Metadata) SpentTokenID() []*token.ID {
4353}
4454
4555// FilterBy returns a new Metadata containing only the metadata that matches the given enrollment IDs.
46- // For Issue actions, for each issue:
47- // - The sender;
48- // - The returned metadata will contain only the outputs whose owner has the given enrollment IDs.
49- // For Transfer actions, for each action:
50- // - The list of token IDs will be empty;
51- // - The returned metadata will contain only the outputs whose owner has the given enrollment IDs;
52- // - The senders are included if and only if there is at least one output whose owner has the given enrollment IDs.
53- // Application metadata is always included
56+ // This is used to share with a party only the metadata they are entitled to see.
57+ //
58+ // For Issue actions:
59+ // - The issuer information is always included.
60+ // - Only metadata for outputs owned by the given enrollment IDs is included.
61+ //
62+ // For Transfer actions:
63+ // - Only metadata for outputs owned by the given enrollment IDs is included.
64+ // - Sender information is included if and only if there is at least one output owned by the given enrollment IDs.
65+ //
66+ // Application metadata is always included.
5467func (m * Metadata ) FilterBy (ctx context.Context , eIDs ... string ) (* Metadata , error ) {
5568 if len (eIDs ) == 0 {
5669 return m , nil
5770 }
5871
5972 eIDSet := collections .NewSet (eIDs ... )
6073
74+ // Filter issue metadata.
6175 issues , err := m .filterIssues (ctx , m .TokenRequestMetadata .Issues , eIDSet )
6276 if err != nil {
6377 return nil , errors .WithMessagef (err , "failed filtering issues" )
6478 }
79+ // Filter transfer metadata.
6580 transfers , err := m .filterTransfers (ctx , m .TokenRequestMetadata .Transfers , eIDSet )
6681 if err != nil {
6782 return nil , errors .WithMessagef (err , "failed filtering transfers" )
@@ -77,7 +92,6 @@ func (m *Metadata) FilterBy(ctx context.Context, eIDs ...string) (*Metadata, err
7792 Logger : m .Logger ,
7893 }
7994
80- // TODO: update this log
8195 m .Logger .Debugf ("filtered metadata for [% x] from [%d:%d] to [%d:%d]" ,
8296 eIDs ,
8397 len (m .TokenRequestMetadata .Issues ), len (m .TokenRequestMetadata .Transfers ),
@@ -86,6 +100,7 @@ func (m *Metadata) FilterBy(ctx context.Context, eIDs ...string) (*Metadata, err
86100 return clone , nil
87101}
88102
103+ // filterIssues filters the issue metadata based on the provided enrollment IDs.
89104func (m * Metadata ) filterIssues (ctx context.Context , issues []* driver.IssueMetadata , eIDSet collections.Set [string ]) ([]* driver.IssueMetadata , error ) {
90105 cloned := make ([]* driver.IssueMetadata , 0 , len (issues ))
91106 for _ , issue := range m .TokenRequestMetadata .Issues {
@@ -98,12 +113,15 @@ func (m *Metadata) filterIssues(ctx context.Context, issues []*driver.IssueMetad
98113
99114 counter := 0
100115 for _ , output := range issue .Outputs {
116+ // Check if any of the receivers of the output matches the enrollment IDs.
101117 if found , err := m .contains (ctx , output .Receivers , eIDSet ); err != nil {
102118 return nil , errors .WithMessagef (err , "failed checking receivers" )
103119 } else if found {
120+ // If matched, include the full output metadata.
104121 clone .Outputs = append (clone .Outputs , output )
105122 counter ++
106123 } else {
124+ // If not matched, include a nil entry to preserve the indexing.
107125 clone .Outputs = append (clone .Outputs , nil )
108126 }
109127 }
@@ -115,6 +133,7 @@ func (m *Metadata) filterIssues(ctx context.Context, issues []*driver.IssueMetad
115133 return cloned , nil
116134}
117135
136+ // filterTransfers filters the transfer metadata based on the provided enrollment IDs.
118137func (m * Metadata ) filterTransfers (ctx context.Context , issues []* driver.TransferMetadata , eIDSet collections.Set [string ]) ([]* driver.TransferMetadata , error ) {
119138 cloned := make ([]* driver.TransferMetadata , 0 , len (issues ))
120139 for _ , transfer := range m .TokenRequestMetadata .Transfers {
@@ -124,8 +143,7 @@ func (m *Metadata) filterTransfers(ctx context.Context, issues []*driver.Transfe
124143 ExtraSigners : transfer .ExtraSigners ,
125144 }
126145
127- // Filter outputs
128- // if the receiver has the given enrollment ID, add it. Otherwise, add empty entries
146+ // Filter outputs: if the receiver has the given enrollment ID, add it. Otherwise, add empty entries.
129147 counter := 0
130148 for _ , output := range transfer .Outputs {
131149 if found , err := m .contains (ctx , output .Receivers , eIDSet ); err != nil {
@@ -138,13 +156,11 @@ func (m *Metadata) filterTransfers(ctx context.Context, issues []*driver.Transfe
138156 }
139157 }
140158
141- // if counter == 0, it means that this transfer does not contain any output for the given enrollment IDs.
142- // Therefore, no metadata should be given to the passed enrollment IDs.
143- // if counter > 0, it means that this transfer contains at least one output for the given enrollment IDs.
144- // Append the senders to the transfer metadata.
159+ // Prepare empty input metadata entries.
145160 for range transfer .Inputs {
146161 clone .Inputs = append (clone .Inputs , & driver.TransferInputMetadata {})
147162 }
163+ // If at least one output matched, include the sender information for all inputs.
148164 if counter > 0 {
149165 for i , input := range transfer .Inputs {
150166 clone .Inputs [i ].Senders = input .Senders
@@ -158,13 +174,15 @@ func (m *Metadata) filterTransfers(ctx context.Context, issues []*driver.Transfe
158174 return cloned , nil
159175}
160176
177+ // contains checks if any of the given auditable identities matches the provided enrollment IDs.
161178func (m * Metadata ) contains (ctx context.Context , receivers []* driver.AuditableIdentity , eIDSet collections.Set [string ]) (bool , error ) {
162179 for _ , receiver := range receivers {
163- // If the receiver has the given enrollment ID, add it
180+ // Resolve the enrollment ID of the receiver.
164181 recipientEID , err := m .WalletService .GetEnrollmentID (ctx , receiver .Identity , receiver .AuditInfo )
165182 if err != nil {
166183 return false , errors .Wrap (err , "failed getting enrollment ID" )
167184 }
185+ // Check if the enrollment ID is in the set.
168186 if eIDSet .Contains (recipientEID ) {
169187 logger .Debugf ("eid [%s] found in list [%v]" , recipientEID , eIDSet )
170188
@@ -177,7 +195,7 @@ func (m *Metadata) contains(ctx context.Context, receivers []*driver.AuditableId
177195 return false , nil
178196}
179197
180- // Issue returns the i-th issue metadata, if present
198+ // Issue returns the i-th issue metadata, if present.
181199func (m * Metadata ) Issue (i int ) (* IssueMetadata , error ) {
182200 if i >= len (m .TokenRequestMetadata .Issues ) {
183201 return nil , errors .Errorf ("index [%d] out of range [0:%d]" , i , len (m .TokenRequestMetadata .Issues ))
@@ -186,7 +204,7 @@ func (m *Metadata) Issue(i int) (*IssueMetadata, error) {
186204 return & IssueMetadata {IssueMetadata : m .TokenRequestMetadata .Issues [i ]}, nil
187205}
188206
189- // Transfer returns the i-th transfer metadata, if present
207+ // Transfer returns the i-th transfer metadata, if present.
190208func (m * Metadata ) Transfer (i int ) (* TransferMetadata , error ) {
191209 if i >= len (m .TokenRequestMetadata .Transfers ) {
192210 return nil , errors .Errorf ("index [%d] out of range [0:%d]" , i , len (m .TokenRequestMetadata .Transfers ))
@@ -195,48 +213,53 @@ func (m *Metadata) Transfer(i int) (*TransferMetadata, error) {
195213 return & TransferMetadata {TransferMetadata : m .TokenRequestMetadata .Transfers [i ]}, nil
196214}
197215
198- // IssueMetadata contains the metadata of an issue action
216+ // IssueMetadata contains the metadata of an issue action.
199217type IssueMetadata struct {
200218 * driver.IssueMetadata
201219}
202220
203- // Match returns true if the given action matches this metadata
221+ // Match returns true if the given action matches this metadata.
222+ // It performs a deep check of inputs, outputs, extra signers, and the issuer identity.
204223func (m * IssueMetadata ) Match (action * IssueAction ) error {
205224 if action == nil {
206225 return errors .New ("can't match issue metadata to issue action: nil issue action" )
207226 }
208227
209- // validate action
228+ // Validate the action's structure.
210229 if err := action .Validate (); err != nil {
211230 return errors .Wrap (err , "failed validating issue action" )
212231 }
213232
214- // check inputs
233+ // Check that the number of inputs matches.
215234 if len (m .Inputs ) != action .NumInputs () {
216235 return errors .Errorf ("expected [%d] inputs but got [%d]" , len (m .Inputs ), action .NumInputs ())
217236 }
218237
219- // check outputs
238+ // Check that the number of outputs matches.
220239 if len (m .Outputs ) != action .NumOutputs () {
221240 return errors .Errorf ("expected [%d] outputs but got [%d]" , len (m .Outputs ), action .NumOutputs ())
222241 }
223242
224- // extra signer
225- extraSigner := action .a .ExtraSigners ()
226- if len (m .ExtraSigners ) != len (extraSigner ) {
227- return errors .Errorf ("expected [%d] extra signers but got [%d]" , len (extraSigner ), len (m .ExtraSigners ))
243+ // Check that the extra signers are the same.
244+ extraSigners := action .a .ExtraSigners ()
245+ if len (m .ExtraSigners ) != len (extraSigners ) {
246+ return errors .Errorf ("expected [%d] extra signers but got [%d]" , len (extraSigners ), len (m .ExtraSigners ))
228247 }
229- // check that the extra signers are the same
230- for i , signer := range extraSigner {
248+ for i , signer := range extraSigners {
231249 if ! slices .ContainsFunc (m .ExtraSigners , signer .Equal ) {
232250 return errors .Errorf ("expected extra signer [%s] but got [%s]" , signer , m .ExtraSigners [i ])
233251 }
234252 }
235253
254+ // Check that the issuer identity matches.
255+ if ! m .Issuer .Identity .Equal (action .GetIssuer ()) {
256+ return errors .Errorf ("expected issuer [%s] but got [%s]" , m .Issuer .Identity , action .GetIssuer ())
257+ }
258+
236259 return nil
237260}
238261
239- // IsOutputAbsent returns true if the given output's metadata is absent
262+ // IsOutputAbsent returns true if the j-th output's metadata is absent (e.g., filtered out).
240263func (m * IssueMetadata ) IsOutputAbsent (j int ) bool {
241264 if j < 0 || j >= len (m .Outputs ) {
242265 return true
@@ -245,63 +268,64 @@ func (m *IssueMetadata) IsOutputAbsent(j int) bool {
245268 return m .Outputs [j ] == nil
246269}
247270
248- // TransferMetadata contains the metadata of a transfer action
271+ // TransferMetadata contains the metadata of a transfer action.
249272type TransferMetadata struct {
250273 * driver.TransferMetadata
251274}
252275
253- // Match returns true if the given action matches this metadata
276+ // Match returns true if the given action matches this metadata.
277+ // It performs a deep check of inputs, outputs, extra signers, and the issuer identity (if present).
254278func (m * TransferMetadata ) Match (action * TransferAction ) error {
255279 if action == nil {
256280 return errors .New ("can't match transfer metadata to transfer action: nil issue action" )
257281 }
258282
259- // validate action
283+ // Validate the action's structure.
260284 if err := action .Validate (); err != nil {
261285 return errors .Wrap (err , "failed validating issue action" )
262286 }
263287
264- // inputs
288+ // Check that the number of inputs matches.
265289 if len (m .Inputs ) != action .NumInputs () {
266290 return errors .Errorf ("expected [%d] inputs but got [%d]" , len (m .Inputs ), action .NumInputs ())
267291 }
268292
269- // outputs
293+ // Check that the number of outputs matches.
270294 if len (m .Outputs ) != action .NumOutputs () {
271295 return errors .Errorf ("expected [%d] outputs but got [%d]" , len (m .Outputs ), action .NumOutputs ())
272296 }
273297
274- // extra signer
275- extraSigner := action .ExtraSigners ()
276- if len (m .ExtraSigners ) != len (extraSigner ) {
277- return errors .Errorf ("expected [%d] extra signers but got [%d]" , len (m .ExtraSigners ), len (extraSigner ))
298+ // Check that the extra signers are the same.
299+ extraSigners := action .ExtraSigners ()
300+ if len (m .ExtraSigners ) != len (extraSigners ) {
301+ return errors .Errorf ("expected [%d] extra signers but got [%d]" , len (m .ExtraSigners ), len (extraSigners ))
278302 }
279- // check that the extra signers are the same
280- for i , signer := range extraSigner {
303+ for i , signer := range extraSigners {
281304 if ! signer .Equal (m .ExtraSigners [i ]) {
282305 return errors .Errorf ("expected extra signer [%s] but got [%s]" , m .ExtraSigners [i ], signer )
283306 }
284307 }
285308
309+ // Check that the issuer identity matches, if present in the metadata.
286310 if ! m .Issuer .Equal (action .GetIssuer ()) {
287311 return errors .Errorf ("expected issuer [%s] but got [%s]" , m .Issuer , action .GetIssuer ().Bytes ())
288312 }
289313
290314 return nil
291315}
292316
293- // IsOutputAbsent returns true if the given output's metadata is absent
317+ // IsOutputAbsent returns true if the j-th output's metadata is absent (e.g., filtered out).
294318func (m * TransferMetadata ) IsOutputAbsent (j int ) bool {
295- if j >= len (m .Outputs ) {
319+ if j < 0 || j >= len (m .Outputs ) {
296320 return true
297321 }
298322
299323 return m .Outputs [j ] == nil
300324}
301325
302- // IsInputAbsent returns true if the given input's metadata is absent
326+ // IsInputAbsent returns true if the j-th input's metadata is absent (e.g., filtered out).
303327func (m * TransferMetadata ) IsInputAbsent (j int ) bool {
304- if j >= len (m .Inputs ) {
328+ if j < 0 || j >= len (m .Inputs ) {
305329 return true
306330 }
307331
0 commit comments