forked from opengsn/gsn
/
memory_store.go
107 lines (85 loc) · 2.79 KB
/
memory_store.go
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
package txstore
import (
"container/list"
"fmt"
"sync"
"code.cloudfoundry.org/clock"
"github.com/ethereum/go-ethereum/core/types"
)
type MemoryTxStore struct {
transactions *list.List
mutex *sync.Mutex
clock clock.Clock
}
func NewMemoryTxStore(clk clock.Clock) *MemoryTxStore {
if clk == nil {
clk = clock.NewClock()
}
return &MemoryTxStore{
transactions: list.New(),
mutex: &sync.Mutex{},
clock: clk,
}
}
// ListTransactions returns all transactions on the store, useful for testing
func (store *MemoryTxStore) ListTransactions() (txs []*TimestampedTransaction, err error) {
txs = make([]*TimestampedTransaction, 0, 20)
for e := store.transactions.Front(); e != nil; e = e.Next() {
txs = append(txs, e.Value.(*TimestampedTransaction))
}
return
}
// GetFirstTransaction returns transaction with lowest nonce
func (store *MemoryTxStore) GetFirstTransaction() (tx *TimestampedTransaction, err error) {
front := store.transactions.Front()
if front == nil {
return nil, nil
}
return front.Value.(*TimestampedTransaction), nil
}
// SaveTransaction dates and stores transaction sorted by ascending nonce
func (store *MemoryTxStore) SaveTransaction(tx *types.Transaction) (err error) {
store.mutex.Lock()
defer store.mutex.Unlock()
timedtx := &TimestampedTransaction{tx, store.clock.Now().Unix()}
for e := store.transactions.Front(); e != nil; e = e.Next() {
if e.Value.(*TimestampedTransaction).Nonce() > tx.Nonce() {
store.transactions.InsertBefore(timedtx, e)
return
}
}
store.transactions.PushBack(timedtx)
return
}
// UpdateTransactionByNonce updates a transaction given its nonce, returns error if tx with same nonce does not exist
func (store *MemoryTxStore) UpdateTransactionByNonce(tx *types.Transaction) (err error) {
store.mutex.Lock()
defer store.mutex.Unlock()
timedtx := &TimestampedTransaction{tx, store.clock.Now().Unix()}
for e := store.transactions.Front(); e != nil; e = e.Next() {
if e.Value.(*TimestampedTransaction).Nonce() == tx.Nonce() {
e.Value = timedtx
return nil
}
}
return fmt.Errorf("Could not find transaction with nonce %d", tx.Nonce())
}
// RemoveTransactionsLessThanNonce removes all transactions with nonce values up to the specified value inclusive
func (store *MemoryTxStore) RemoveTransactionsLessThanNonce(nonce uint64) (err error) {
store.mutex.Lock()
defer store.mutex.Unlock()
for e := store.transactions.Front(); e != nil && e.Value.(*TimestampedTransaction).Nonce() < nonce; e = store.transactions.Front() {
store.transactions.Remove(e)
}
return
}
// Clear removes all transactions stored
func (store *MemoryTxStore) Clear() (err error) {
store.mutex.Lock()
defer store.mutex.Unlock()
store.transactions = list.New()
return
}
func (store *MemoryTxStore) Close() (err error) {
return nil
}