trees/checkpoint: Add checkpoint.Checkpoint#8830
Conversation
634f52d to
c31714e
Compare
c31714e to
e4bc604
Compare
| // serializing. | ||
| // | ||
| // https://c2sp.org/tlog-checkpoint | ||
| func (c Checkpoint) String() string { |
There was a problem hiding this comment.
The Checkpoint type contains both a slice (Extensions) and a potentially-large array (Tree.Hash), so we should probably not be passing Checkpoints around by value. These should be pointer receivers, and Parse should return a *Checkpoint.
|
|
||
| // validNoteLine reports whether s is a valid signed-note line: UTF-8 with no | ||
| // control character below U+0020. | ||
| func validNoteLine(s string) bool { |
There was a problem hiding this comment.
Are checkpoints the only kind of signed note we're going to be producing or parsing? If not, then this and other helpers should probably be in a separate note package.
| return "", errors.New("empty checkpoint origin") | ||
| } | ||
| if !validNoteLine(c.Origin) { | ||
| return "", errors.New("checkpoint origin contains a control character or invalid UTF-8") |
There was a problem hiding this comment.
There'd be no need for this verbose "or" error line if validNoteLine returned a more-specific error itself. It would also allow you to avoid repeating this same error message several times below.
| return "", errors.New("checkpoint extension line contains a control character or invalid UTF-8") | ||
| } | ||
| } | ||
| return c.String(), nil |
There was a problem hiding this comment.
I'm not sure I love this relationship between String() and Marshal(). I like having both methods! But:
a) I think that most callers of .String() (e.g. test got/want error output) expect the result of that method to be single-line; and
b) Having two ways to get the exact same result, one of which is unsafe, feels unsafe to me.
How would you feel about having .String() instead return a purposefully non-compliant single-line result, specifically for internal debugging use, while .Marshal() constructs the actual format?
| // verifiers. | ||
| // | ||
| // https://c2sp.org/signed-note | ||
| func Open(signedNote []byte, verifiers note.Verifiers) (Checkpoint, *note.Note, error) { |
There was a problem hiding this comment.
Who are the prospective callers of this function? Why do they want access to the underlying Note, and not just the Checkpoint? They're just different in-memory views onto the same text, right?
Add
Checkpointto represent a tlog-checkpoint note body, with.String()to serialize it and.Marshal()to serialize with field validation. AddParse()to parse an unsigned body andOpen()to verify a signed note and parse its body into aCheckpoint.A note to reviewers: this package and its tests were written with assistance from Claude Opus 4.8. That being said, it has been reviewed and extensively revised by myself before submission.