-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathinputlog.go
More file actions
118 lines (104 loc) · 2.98 KB
/
Copy pathinputlog.go
File metadata and controls
118 lines (104 loc) · 2.98 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
// Copyright 2025 Google LLC. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package vindex
import (
"context"
"iter"
"net/http"
"net/url"
"github.com/transparency-dev/formats/log"
"github.com/transparency-dev/tessera/api"
"github.com/transparency-dev/tessera/client"
"golang.org/x/mod/sumdb/note"
)
// fetcher describes a struct which knows how to retrieve tlog-tiles artifacts from a log.
type fetcher interface {
ReadCheckpoint(ctx context.Context) ([]byte, error)
ReadTile(ctx context.Context, l, i uint64, p uint8) ([]byte, error)
ReadEntryBundle(ctx context.Context, i uint64, p uint8) ([]byte, error)
}
type InputLogOpts struct {
HttpClient *http.Client
Origin string
NumReaders uint
}
func NewTiledInputLog(base *url.URL, v note.Verifier, o InputLogOpts) (InputLog, error) {
// Set any missing optional values to their defaults
if o.HttpClient == nil {
o.HttpClient = http.DefaultClient
}
if len(o.Origin) == 0 {
o.Origin = v.Name()
}
if o.NumReaders == 0 {
o.NumReaders = 4
}
var src fetcher
if base.Scheme == "file" {
src = &client.FileFetcher{
Root: base.Path,
}
} else {
var err error
src, err = client.NewHTTPFetcher(base, o.HttpClient)
if err != nil {
return nil, err
}
}
return logReaderSource{
f: src,
v: v,
opts: o,
}, nil
}
// logReaderSource adapts a tessera.LogReader to a vindex.InputLog.
type logReaderSource struct {
f fetcher
v note.Verifier
opts InputLogOpts
}
func (s logReaderSource) Checkpoint(ctx context.Context) (checkpoint []byte, err error) {
return s.f.ReadCheckpoint(ctx)
}
func (s logReaderSource) Parse(cpRaw []byte) (*log.Checkpoint, error) {
cp, _, _, err := log.ParseCheckpoint(cpRaw, s.opts.Origin, s.v)
return cp, err
}
func (s logReaderSource) Leaves(ctx context.Context, start, end uint64) iter.Seq2[[]byte, error] {
tsf := func(ctx context.Context) (uint64, error) {
return end, nil
}
bi := client.EntryBundles(ctx, s.opts.NumReaders, tsf, s.f.ReadEntryBundle, start, end-start)
unbundleFn := func(bundle []byte) ([][]byte, error) {
eb := &api.EntryBundle{}
if err := eb.UnmarshalText(bundle); err != nil {
return nil, err
}
return eb.Entries, nil
}
return func(yield func([]byte, error) bool) {
// Unwrap the client.Entry type to return an iterator of []byte only.
for entry, err := range client.Entries(bi, unbundleFn) {
if err != nil {
if !yield(nil, err) {
return
}
continue
}
if !yield(entry.Entry, nil) {
return
}
}
}
}