A very experimental PLC implementation which uses BFT consensus for decentralization
1package transaction
2
3import (
4 "sync"
5 "time"
6
7 "github.com/bits-and-blooms/bloom/v3"
8 "github.com/cosmos/iavl"
9 "github.com/gbl08ma/stacktrace"
10)
11
12type readTx struct {
13 ts time.Time
14 height int64
15
16 mutableTree *iavl.MutableTree // only present if upgradable
17 tree ReadTree
18 db ExtendedDB
19
20 bloomMu *sync.RWMutex
21 bloomFilter *bloom.BloomFilter
22 bloomSeq *uint64
23
24 operationCounter func(tx Read) (uint64, error)
25}
26
27// Height implements [Read].
28func (t *readTx) Height() int64 {
29 return t.height
30}
31
32// Timestamp implements [Read].
33func (t *readTx) Timestamp() time.Time {
34 return t.ts
35}
36
37// CountOperations implements [Read].
38func (t *readTx) CountOperations() (uint64, error) {
39 count, err := t.operationCounter(t)
40 return count, stacktrace.Propagate(err)
41}
42
43// Tree implements [Read].
44func (t *readTx) Tree() ReadTree {
45 if t.mutableTree != nil {
46 return t.mutableTree
47 }
48 return t.tree
49}
50
51// IndexDB implements [Read].
52func (t *readTx) IndexDB() IndexReader {
53 return t.db
54}
55
56// TestDIDBloomFilter implements [Read].
57func (t *readTx) TestDIDBloomFilter(did []byte) bool {
58 t.bloomMu.RLock()
59 defer t.bloomMu.RUnlock()
60 return t.bloomFilter.Test(did)
61}
62
63// Upgrade implements [Read].
64func (t *readTx) Upgrade() (Write, error) {
65 if t.mutableTree == nil {
66 return nil, stacktrace.NewError("historical transaction is not upgradable to a write transaction")
67 }
68 return &writeTx{
69 readTx: t,
70 unsavedBloomAdditions: map[string]struct{}{},
71 }, nil
72}
73
74// UpgradeForIndexOnly implements [Read].
75func (t *readTx) UpgradeForIndexOnly() (WriteIndex, error) {
76 return &writeIndexTx{
77 db: t.db,
78 }, nil
79}