@@ -47,6 +47,7 @@ type Handle struct {
4747
4848 indices map [uint32 ]* Index
4949 aas map [uint32 ]* os.File
50+ evs map [uint32 ]* os.File
5051 trees map [uint32 ]* Tree
5152
5253 batchNumbersCache []uint32 // cache for existing batches
@@ -69,6 +70,10 @@ func (ca *Handle) Close() error {
6970 r .Close ()
7071 }
7172
73+ for _ , r := range ca .evs {
74+ r .Close ()
75+ }
76+
7277 for _ , t := range ca .trees {
7378 t .Close ()
7479 }
@@ -97,7 +102,7 @@ func (h *Handle) dropQueue() error {
97102//
98103// For each entry, if checksum is not nil, makes sure the assertion
99104// matches the checksum
100- func (h * Handle ) QueueMultiple (it func (yield func (a mtc.AssertionRequest ) error ) error ) error {
105+ func (h * Handle ) QueueMultiple (it func (yield func (ar mtc.AssertionRequest ) error ) error ) error {
101106 if h .closed {
102107 return ErrClosed
103108 }
@@ -109,8 +114,8 @@ func (h *Handle) QueueMultiple(it func(yield func(a mtc.AssertionRequest) error)
109114 defer w .Close ()
110115 bw := bufio .NewWriter (w )
111116
112- if err := it (func (a mtc.AssertionRequest ) error {
113- buf , err := a .MarshalBinary ()
117+ if err := it (func (ar mtc.AssertionRequest ) error {
118+ buf , err := ar .MarshalBinary ()
114119 if err != nil {
115120 return err
116121 }
@@ -140,9 +145,9 @@ func (h *Handle) QueueMultiple(it func(yield func(a mtc.AssertionRequest) error)
140145// Queue assertion for publication.
141146//
142147// If checksum is not nil, makes sure assertion matches the checksum.
143- func (h * Handle ) Queue (a mtc.AssertionRequest ) error {
144- return h .QueueMultiple (func (yield func (a mtc.AssertionRequest ) error ) error {
145- return yield (a )
148+ func (h * Handle ) Queue (ar mtc.AssertionRequest ) error {
149+ return h .QueueMultiple (func (yield func (ar mtc.AssertionRequest ) error ) error {
150+ return yield (ar )
146151 })
147152}
148153
@@ -154,6 +159,7 @@ func Open(path string) (*Handle, error) {
154159 path : path ,
155160 indices : make (map [uint32 ]* Index ),
156161 aas : make (map [uint32 ]* os.File ),
162+ evs : make (map [uint32 ]* os.File ),
157163 trees : make (map [uint32 ]* Tree ),
158164 }
159165 if err := h .lock (); err != nil {
@@ -209,6 +215,10 @@ func (h Handle) aaPath(number uint32) string {
209215 return gopath .Join (h .batchPath (number ), "abridged-assertions" )
210216}
211217
218+ func (h Handle ) evPath (number uint32 ) string {
219+ return gopath .Join (h .batchPath (number ), "evidence" )
220+ }
221+
212222func (h Handle ) batchPath (number uint32 ) string {
213223 return gopath .Join (h .batchesPath (), fmt .Sprintf ("%d" , number ))
214224}
@@ -327,7 +337,7 @@ func (h *Handle) WalkQueue(f func(mtc.AssertionRequest) error) error {
327337 var (
328338 prefix [2 ]byte
329339 aLen uint16
330- a mtc.AssertionRequest
340+ ar mtc.AssertionRequest
331341 )
332342 _ , err := io .ReadFull (br , prefix [:])
333343 if err == io .EOF {
@@ -345,12 +355,12 @@ func (h *Handle) WalkQueue(f func(mtc.AssertionRequest) error) error {
345355 return fmt .Errorf ("Reading queue: %w" , err )
346356 }
347357
348- err = a .UnmarshalBinary (buf )
358+ err = ar .UnmarshalBinary (buf )
349359 if err != nil {
350360 return fmt .Errorf ("Parsing queue: %w" , err )
351361 }
352362
353- err = f (a )
363+ err = f (ar )
354364 if err != nil {
355365 return err
356366 }
@@ -416,6 +426,14 @@ func (h *Handle) closeBatch(batch uint32) error {
416426 delete (h .aas , batch )
417427 }
418428
429+ if r , ok := h .evs [batch ]; ok {
430+ err := r .Close ()
431+ if err != nil {
432+ return fmt .Errorf ("closing evidence for %d: %w" , batch , err )
433+ }
434+ delete (h .evs , batch )
435+ }
436+
419437 if r , ok := h .trees [batch ]; ok {
420438 err := r .Close ()
421439 if err != nil {
@@ -472,10 +490,25 @@ func (ca *Handle) aaFileFor(batch uint32) (*os.File, error) {
472490 return r , nil
473491}
474492
493+ // Returns file handle to evidence file for the given batch.
494+ func (ca * Handle ) evFileFor (batch uint32 ) (* os.File , error ) {
495+ if r , ok := ca .evs [batch ]; ok {
496+ return r , nil
497+ }
498+
499+ r , err := os .Open (ca .evPath (batch ))
500+ if err != nil {
501+ return nil , err
502+ }
503+
504+ return r , nil
505+ }
506+
475507type keySearchResult struct {
476508 Batch uint32
477509 SequenceNumber uint64
478510 Offset uint64
511+ EvidenceOffset uint64
479512}
480513
481514// Returns the certificate for an issued assertion
@@ -516,7 +549,46 @@ func (ca *Handle) CertificateFor(a mtc.Assertion) (*mtc.BikeshedCertificate, err
516549 }, nil
517550}
518551
519- // Search for AbridgedAssertions's batch/seqno/offset by key.
552+ var ErrShortCircuit = errors .New ("short circuit" )
553+
554+ // Returns the evidence for an issued assertion
555+ func (ca * Handle ) EvidenceFor (a mtc.Assertion ) (* mtc.Evidence , error ) {
556+ aa := a .Abridge ()
557+ var key [mtc .HashLen ]byte
558+ err := aa .Key (key [:])
559+ if err != nil {
560+ return nil , err
561+ }
562+ res , err := ca .aaByKey (key [:])
563+ if err != nil {
564+ return nil , fmt .Errorf ("searching by key: %w" , err )
565+ }
566+
567+ if res == nil {
568+ return nil , fmt .Errorf ("no assertion with key %x on record" , key )
569+ }
570+
571+ var ev * mtc.Evidence
572+ evFile , err := ca .evFileFor (res .Batch )
573+ if err != nil {
574+ return nil , err
575+ }
576+ _ , err = evFile .Seek (int64 (res .EvidenceOffset ), 0 )
577+ if err != nil {
578+ return nil , err
579+ }
580+ err = mtc .UnmarshalEvidenceEntries (evFile , func (_ int , ev2 * mtc.Evidence ) error {
581+ ev = ev2
582+ return ErrShortCircuit
583+ })
584+ if err != ErrShortCircuit {
585+ return nil , err
586+ }
587+
588+ return ev , nil
589+ }
590+
591+ // Search for AbridgedAssertions's batch/seqno/offset/evidence_offset by key.
520592func (ca * Handle ) aaByKey (key []byte ) (* keySearchResult , error ) {
521593 batches , err := ca .listBatchRange ()
522594 if err != nil {
@@ -527,7 +599,7 @@ func (ca *Handle) aaByKey(key []byte) (*keySearchResult, error) {
527599 return nil , nil
528600 }
529601
530- for batch := batches .End - 1 ; batch <= batches .End ; batch -- {
602+ for batch := batches .End - 1 ; batch >= batches . Begin && batch <= batches .End ; batch -- {
531603 res , err := ca .aaByKeyIn (batch , key )
532604 if err != nil {
533605 return nil , fmt .Errorf ("Searching in batch %d: %w" , batch , err )
@@ -537,6 +609,7 @@ func (ca *Handle) aaByKey(key []byte) (*keySearchResult, error) {
537609 Batch : batch ,
538610 SequenceNumber : res .SequenceNumber ,
539611 Offset : res .Offset ,
612+ EvidenceOffset : res .EvidenceOffset ,
540613 }, nil
541614 }
542615 }
@@ -830,34 +903,34 @@ func (h *Handle) issueBatchTo(dir string, batch mtc.Batch, empty bool) error {
830903 evBW := bufio .NewWriter (evW )
831904
832905 if ! empty {
833- err = h .WalkQueue (func (a mtc.AssertionRequest ) error {
834- aa := a .Assertion .Abridge ()
906+ err = h .WalkQueue (func (ar mtc.AssertionRequest ) error {
907+ aa := ar .Assertion .Abridge ()
835908 buf , err := aa .MarshalBinary ()
836909 if err != nil {
837- return fmt .Errorf ("Marshalling assertion %x: %w" , a .Checksum , err )
910+ return fmt .Errorf ("Marshalling assertion %x: %w" , ar .Checksum , err )
838911 }
839912
840913 _ , err = aasBW .Write (buf )
841914 if err != nil {
842915 return fmt .Errorf (
843916 "Writing assertion %x to %s: %w" ,
844- a .Checksum ,
917+ ar .Checksum ,
845918 aasPath ,
846919 err ,
847920 )
848921 }
849922
850- ev := a .Evidence
923+ ev := ar .Evidence
851924 buf , err = ev .MarshalBinary ()
852925 if err != nil {
853- return fmt .Errorf ("Marshalling evidence %x: %w" , a .Checksum , err )
926+ return fmt .Errorf ("Marshalling evidence %x: %w" , ar .Checksum , err )
854927 }
855928
856929 _ , err = evBW .Write (buf )
857930 if err != nil {
858931 return fmt .Errorf (
859932 "Writing evidence %x to %s: %w" ,
860- a .Checksum ,
933+ ar .Checksum ,
861934 evPath ,
862935 err ,
863936 )
0 commit comments