···11MIT License
2233Copyright (c) 2025 me@haileyok.com
44+Copyright (c) 2026 julien@rbrt.fr
4556Permission is hereby granted, free of charge, to any person obtaining a copy
67of this software and associated documentation files (the "Software"), to deal
README.md
readme.md
+84
blockstore/recording.go
···11+package blockstore
22+33+import (
44+ "context"
55+ "fmt"
66+77+ boxoblockstore "github.com/ipfs/boxo/blockstore"
88+ blocks "github.com/ipfs/go-block-format"
99+ "github.com/ipfs/go-cid"
1010+)
1111+1212+// RecordingBlockstore wraps a Blockstore and records all reads and writes
1313+// performed against it, for later inspection.
1414+type RecordingBlockstore struct {
1515+ base boxoblockstore.Blockstore
1616+1717+ inserts map[cid.Cid]blocks.Block
1818+ reads map[cid.Cid]blocks.Block
1919+}
2020+2121+func NewRecording(base boxoblockstore.Blockstore) *RecordingBlockstore {
2222+ return &RecordingBlockstore{
2323+ base: base,
2424+ inserts: make(map[cid.Cid]blocks.Block),
2525+ reads: make(map[cid.Cid]blocks.Block),
2626+ }
2727+}
2828+2929+func (bs *RecordingBlockstore) Has(ctx context.Context, c cid.Cid) (bool, error) {
3030+ return bs.base.Has(ctx, c)
3131+}
3232+3333+func (bs *RecordingBlockstore) Get(ctx context.Context, c cid.Cid) (blocks.Block, error) {
3434+ b, err := bs.base.Get(ctx, c)
3535+ if err != nil {
3636+ return nil, err
3737+ }
3838+ bs.reads[c] = b
3939+ return b, nil
4040+}
4141+4242+func (bs *RecordingBlockstore) GetSize(ctx context.Context, c cid.Cid) (int, error) {
4343+ return bs.base.GetSize(ctx, c)
4444+}
4545+4646+func (bs *RecordingBlockstore) DeleteBlock(ctx context.Context, c cid.Cid) error {
4747+ return bs.base.DeleteBlock(ctx, c)
4848+}
4949+5050+func (bs *RecordingBlockstore) Put(ctx context.Context, block blocks.Block) error {
5151+ if err := bs.base.Put(ctx, block); err != nil {
5252+ return err
5353+ }
5454+ bs.inserts[block.Cid()] = block
5555+ return nil
5656+}
5757+5858+func (bs *RecordingBlockstore) PutMany(ctx context.Context, blks []blocks.Block) error {
5959+ if err := bs.base.PutMany(ctx, blks); err != nil {
6060+ return err
6161+ }
6262+ for _, b := range blks {
6363+ bs.inserts[b.Cid()] = b
6464+ }
6565+ return nil
6666+}
6767+6868+func (bs *RecordingBlockstore) AllKeysChan(ctx context.Context) (<-chan cid.Cid, error) {
6969+ return nil, fmt.Errorf("iteration not allowed on recording blockstore")
7070+}
7171+7272+func (bs *RecordingBlockstore) HashOnRead(bool) {}
7373+7474+func (bs *RecordingBlockstore) GetWriteLog() map[cid.Cid]blocks.Block {
7575+ return bs.inserts
7676+}
7777+7878+func (bs *RecordingBlockstore) GetReadLog() []blocks.Block {
7979+ result := make([]blocks.Block, 0, len(bs.reads))
8080+ for _, b := range bs.reads {
8181+ result = append(result, b)
8282+ }
8383+ return result
8484+}