Skip to content

Commit 6460c94

Browse files
committed
Address Bas' feedback and fix some bugs
- Use 'ar' for AssertionRequests to reduce risk of variable shadowing. - bugfix: fix range when iterating over batches. Previously, there was no lower limit to the loop. And since we're iterating backwards with a uint32, keep the upper limit to avoid integer underflow. - Finish adding index support for evidence, so you can now `mtc ca evidence` will properly check the evidence file for an assertion's evidence. - Include Evidence in the AssertionRequest checksum. - Use 'assertion-request' instead of 'assertion' for cli flags.
1 parent 6055bf0 commit 6460c94

File tree

5 files changed

+207
-90
lines changed

5 files changed

+207
-90
lines changed

ca/ca.go

Lines changed: 91 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
212222
func (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+
475507
type 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.
520592
func (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
)

ca/index.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ type Index struct {
4141
type IndexSearchResult struct {
4242
SequenceNumber uint64
4343
Offset uint64
44+
EvidenceOffset uint64
4445
}
4546

4647
// Opens an index
@@ -139,6 +140,7 @@ func (h *Index) Search(hash []byte) (*IndexSearchResult, error) {
139140
ss := cryptobyte.String(val[:])
140141
ss.ReadUint64(&ret.SequenceNumber)
141142
ss.ReadUint64(&ret.Offset)
143+
ss.ReadUint64(&ret.EvidenceOffset)
142144
return &ret, nil
143145
case -1: // tmp < needle
144146
a.Set(&tmp)

0 commit comments

Comments
 (0)