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
package derive
import (
"context"
"fmt"
"github.com/ethereum-optimism/optimism/op-service/eth"
"github.com/ethereum/go-ethereum/log"
)
// PlasmaDataSource is a data source that fetches inputs from a plasma DA provider given
// their onchain commitments. Same as CalldataSource it will keep attempting to fetch.
type PlasmaDataSource struct {
log log.Logger
src DataIter
fetcher PlasmaInputFetcher
id eth.BlockID
// keep track of a pending commitment so we can keep trying to fetch the input.
comm []byte
}
func NewPlasmaDataSource(log log.Logger, src DataIter, fetcher PlasmaInputFetcher, id eth.BlockID) *PlasmaDataSource {
return &PlasmaDataSource{
log: log,
src: src,
fetcher: fetcher,
id: id,
}
}
func (s *PlasmaDataSource) Next(ctx context.Context) (eth.Data, error) {
if s.comm == nil {
var err error
// the l1 source returns the input commitment for the batch.
s.comm, err = s.src.Next(ctx)
if err != nil {
return nil, err
}
}
// use the commitment to fetch the input from the plasma DA provider.
resp, err := s.fetcher.GetInput(ctx, s.comm, s.id.Number)
if err != nil {
// return temporary error so we can keep retrying.
return nil, NewTemporaryError(fmt.Errorf("failed to fetch input data with comm %x from da service: %w", s.comm, err))
}
// reset the commitment so we can fetch the next one from the source at the next iteration.
s.comm = nil
return resp.Data, nil
}