@blinklabs/dingo 0.7.0 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (187) hide show
  1. package/.dingo/blob/000001.sst +0 -0
  2. package/.dingo/blob/000001.vlog +0 -0
  3. package/.dingo/blob/DISCARD +0 -0
  4. package/.dingo/blob/KEYREGISTRY +2 -0
  5. package/.dingo/blob/MANIFEST +0 -0
  6. package/.dingo/metadata.sqlite +0 -0
  7. package/.github/workflows/golangci-lint.yml +1 -1
  8. package/.github/workflows/publish.yml +1 -7
  9. package/README.md +2 -1
  10. package/{bin/dingo → dingo} +0 -0
  11. package/dingo.yaml.example +53 -0
  12. package/package.json +2 -2
  13. package/Dockerfile +0 -25
  14. package/Makefile +0 -53
  15. package/blockfetch.go +0 -144
  16. package/chain/chain.go +0 -504
  17. package/chain/chain_test.go +0 -468
  18. package/chain/errors.go +0 -80
  19. package/chain/event.go +0 -33
  20. package/chain/iter.go +0 -64
  21. package/chainsync/chainsync.go +0 -97
  22. package/chainsync.go +0 -223
  23. package/cmd/dingo/load.go +0 -52
  24. package/cmd/dingo/main.go +0 -118
  25. package/cmd/dingo/serve.go +0 -49
  26. package/config/cardano/node.go +0 -192
  27. package/config/cardano/node_test.go +0 -85
  28. package/config/cardano/preview/README.md +0 -4
  29. package/config/cardano/preview/alonzo-genesis.json +0 -196
  30. package/config/cardano/preview/byron-genesis.json +0 -117
  31. package/config/cardano/preview/config.json +0 -114
  32. package/config/cardano/preview/conway-genesis.json +0 -297
  33. package/config/cardano/preview/shelley-genesis.json +0 -68
  34. package/config.go +0 -245
  35. package/connmanager/connection_manager.go +0 -105
  36. package/connmanager/connection_manager_test.go +0 -185
  37. package/connmanager/event.go +0 -37
  38. package/connmanager/listener.go +0 -140
  39. package/connmanager/outbound.go +0 -93
  40. package/connmanager/socket.go +0 -55
  41. package/connmanager/unix.go +0 -78
  42. package/custom-p2p-topology.json +0 -24
  43. package/custom-p2p-topology.json.backup +0 -24
  44. package/custom-p2p-topology.json.mainnet +0 -37
  45. package/database/account.go +0 -180
  46. package/database/block.go +0 -362
  47. package/database/certs.go +0 -53
  48. package/database/commit_timestamp.go +0 -77
  49. package/database/database.go +0 -118
  50. package/database/database_test.go +0 -62
  51. package/database/drep.go +0 -47
  52. package/database/epoch.go +0 -121
  53. package/database/immutable/chunk.go +0 -182
  54. package/database/immutable/immutable.go +0 -350
  55. package/database/immutable/immutable_test.go +0 -59
  56. package/database/immutable/primary.go +0 -106
  57. package/database/immutable/secondary.go +0 -103
  58. package/database/immutable/testdata/08893.chunk +0 -0
  59. package/database/immutable/testdata/08893.primary +0 -0
  60. package/database/immutable/testdata/08893.secondary +0 -0
  61. package/database/immutable/testdata/08894.chunk +0 -0
  62. package/database/immutable/testdata/08894.primary +0 -0
  63. package/database/immutable/testdata/08894.secondary +0 -0
  64. package/database/immutable/testdata/README.md +0 -4
  65. package/database/plugin/blob/badger/commit_timestamp.go +0 -50
  66. package/database/plugin/blob/badger/database.go +0 -152
  67. package/database/plugin/blob/badger/logger.go +0 -63
  68. package/database/plugin/blob/badger/metrics.go +0 -98
  69. package/database/plugin/blob/blob.go +0 -19
  70. package/database/plugin/blob/store.go +0 -40
  71. package/database/plugin/log.go +0 -27
  72. package/database/plugin/metadata/metadata.go +0 -19
  73. package/database/plugin/metadata/sqlite/account.go +0 -313
  74. package/database/plugin/metadata/sqlite/certs.go +0 -58
  75. package/database/plugin/metadata/sqlite/commit_timestamp.go +0 -68
  76. package/database/plugin/metadata/sqlite/database.go +0 -218
  77. package/database/plugin/metadata/sqlite/drep.go +0 -140
  78. package/database/plugin/metadata/sqlite/epoch.go +0 -120
  79. package/database/plugin/metadata/sqlite/models/account.go +0 -118
  80. package/database/plugin/metadata/sqlite/models/auth_committee_hot.go +0 -26
  81. package/database/plugin/metadata/sqlite/models/drep.go +0 -52
  82. package/database/plugin/metadata/sqlite/models/epoch.go +0 -31
  83. package/database/plugin/metadata/sqlite/models/models.go +0 -46
  84. package/database/plugin/metadata/sqlite/models/pool.go +0 -97
  85. package/database/plugin/metadata/sqlite/models/pparam_update.go +0 -27
  86. package/database/plugin/metadata/sqlite/models/pparams.go +0 -27
  87. package/database/plugin/metadata/sqlite/models/resign_committee_cold.go +0 -27
  88. package/database/plugin/metadata/sqlite/models/stake_vote_delegation.go +0 -27
  89. package/database/plugin/metadata/sqlite/models/tip.go +0 -26
  90. package/database/plugin/metadata/sqlite/models/update_drep.go +0 -27
  91. package/database/plugin/metadata/sqlite/models/utxo.go +0 -30
  92. package/database/plugin/metadata/sqlite/models/vote_delegation.go +0 -26
  93. package/database/plugin/metadata/sqlite/models/vote_registration_delegation.go +0 -15
  94. package/database/plugin/metadata/sqlite/pool.go +0 -240
  95. package/database/plugin/metadata/sqlite/pparams.go +0 -110
  96. package/database/plugin/metadata/sqlite/tip.go +0 -83
  97. package/database/plugin/metadata/sqlite/utxo.go +0 -292
  98. package/database/plugin/metadata/store.go +0 -198
  99. package/database/plugin/option.go +0 -190
  100. package/database/plugin/plugin.go +0 -20
  101. package/database/plugin/register.go +0 -118
  102. package/database/pparams.go +0 -145
  103. package/database/tip.go +0 -45
  104. package/database/txn.go +0 -147
  105. package/database/types/types.go +0 -74
  106. package/database/types/types_test.go +0 -83
  107. package/database/utxo.go +0 -263
  108. package/dist/artifacts.json +0 -1
  109. package/dist/checksums.txt +0 -22
  110. package/dist/config.yaml +0 -253
  111. package/dist/dingo-0.5.0-SNAPSHOT-d9431e4.tar.gz +0 -0
  112. package/dist/dingo-0.5.0-SNAPSHOT-d9431e4.tar.gz.sbom.json +0 -1
  113. package/dist/dingo_0.5.0-SNAPSHOT-d9431e4_darwin_arm64.tar.gz +0 -0
  114. package/dist/dingo_0.5.0-SNAPSHOT-d9431e4_darwin_arm64.tar.gz.sbom.json +0 -1
  115. package/dist/dingo_0.5.0-SNAPSHOT-d9431e4_darwin_x86_64.tar.gz +0 -0
  116. package/dist/dingo_0.5.0-SNAPSHOT-d9431e4_darwin_x86_64.tar.gz.sbom.json +0 -1
  117. package/dist/dingo_0.5.0-SNAPSHOT-d9431e4_linux_amd64.apk +0 -0
  118. package/dist/dingo_0.5.0-SNAPSHOT-d9431e4_linux_amd64.apk.sbom.json +0 -1
  119. package/dist/dingo_0.5.0-SNAPSHOT-d9431e4_linux_amd64.deb +0 -0
  120. package/dist/dingo_0.5.0-SNAPSHOT-d9431e4_linux_amd64.deb.sbom.json +0 -1
  121. package/dist/dingo_0.5.0-SNAPSHOT-d9431e4_linux_amd64.rpm +0 -0
  122. package/dist/dingo_0.5.0-SNAPSHOT-d9431e4_linux_amd64.rpm.sbom.json +0 -1
  123. package/dist/dingo_0.5.0-SNAPSHOT-d9431e4_linux_arm64.apk +0 -0
  124. package/dist/dingo_0.5.0-SNAPSHOT-d9431e4_linux_arm64.apk.sbom.json +0 -1
  125. package/dist/dingo_0.5.0-SNAPSHOT-d9431e4_linux_arm64.deb +0 -0
  126. package/dist/dingo_0.5.0-SNAPSHOT-d9431e4_linux_arm64.deb.sbom.json +0 -1
  127. package/dist/dingo_0.5.0-SNAPSHOT-d9431e4_linux_arm64.rpm +0 -0
  128. package/dist/dingo_0.5.0-SNAPSHOT-d9431e4_linux_arm64.rpm.sbom.json +0 -1
  129. package/dist/dingo_0.5.0-SNAPSHOT-d9431e4_linux_arm64.tar.gz +0 -0
  130. package/dist/dingo_0.5.0-SNAPSHOT-d9431e4_linux_arm64.tar.gz.sbom.json +0 -1
  131. package/dist/dingo_0.5.0-SNAPSHOT-d9431e4_linux_x86_64.tar.gz +0 -0
  132. package/dist/dingo_0.5.0-SNAPSHOT-d9431e4_linux_x86_64.tar.gz.sbom.json +0 -1
  133. package/dist/dingo_darwin_amd64_v1/dingo +0 -0
  134. package/dist/dingo_darwin_arm64_v8.0/dingo +0 -0
  135. package/dist/dingo_linux_amd64_v1/dingo +0 -0
  136. package/dist/dingo_linux_arm64_v8.0/dingo +0 -0
  137. package/dist/homebrew/dingo.rb +0 -51
  138. package/dist/metadata.json +0 -1
  139. package/event/event.go +0 -141
  140. package/event/event_test.go +0 -115
  141. package/event/metrics.go +0 -44
  142. package/go.mod +0 -98
  143. package/go.sum +0 -358
  144. package/internal/config/config.go +0 -145
  145. package/internal/config/config_test.go +0 -118
  146. package/internal/node/load.go +0 -149
  147. package/internal/node/node.go +0 -176
  148. package/internal/version/version.go +0 -33
  149. package/ledger/certs.go +0 -164
  150. package/ledger/chainsync.go +0 -504
  151. package/ledger/delta.go +0 -99
  152. package/ledger/eras/allegra.go +0 -154
  153. package/ledger/eras/alonzo.go +0 -156
  154. package/ledger/eras/babbage.go +0 -154
  155. package/ledger/eras/byron.go +0 -42
  156. package/ledger/eras/conway.go +0 -166
  157. package/ledger/eras/eras.go +0 -44
  158. package/ledger/eras/mary.go +0 -154
  159. package/ledger/eras/shelley.go +0 -164
  160. package/ledger/error.go +0 -19
  161. package/ledger/event.go +0 -50
  162. package/ledger/metrics.go +0 -53
  163. package/ledger/queries.go +0 -258
  164. package/ledger/slot.go +0 -127
  165. package/ledger/slot_test.go +0 -147
  166. package/ledger/state.go +0 -821
  167. package/ledger/view.go +0 -73
  168. package/localstatequery.go +0 -50
  169. package/localtxmonitor.go +0 -44
  170. package/localtxsubmission.go +0 -52
  171. package/mempool/consumer.go +0 -98
  172. package/mempool/mempool.go +0 -322
  173. package/node.go +0 -320
  174. package/peergov/event.go +0 -27
  175. package/peergov/peer.go +0 -67
  176. package/peergov/peergov.go +0 -290
  177. package/peersharing.go +0 -70
  178. package/preview-local-topology.json +0 -23
  179. package/topology/topology.go +0 -69
  180. package/topology/topology_test.go +0 -179
  181. package/tracing.go +0 -65
  182. package/txsubmission.go +0 -233
  183. package/utxorpc/query.go +0 -311
  184. package/utxorpc/submit.go +0 -395
  185. package/utxorpc/sync.go +0 -276
  186. package/utxorpc/utxorpc.go +0 -166
  187. package/utxorpc/watch.go +0 -310
package/ledger/view.go DELETED
@@ -1,73 +0,0 @@
1
- // Copyright 2025 Blink Labs Software
2
- //
3
- // Licensed under the Apache License, Version 2.0 (the "License");
4
- // you may not use this file except in compliance with the License.
5
- // You may obtain a copy of the License at
6
- //
7
- // http://www.apache.org/licenses/LICENSE-2.0
8
- //
9
- // Unless required by applicable law or agreed to in writing, software
10
- // distributed under the License is distributed on an "AS IS" BASIS,
11
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
- // See the License for the specific language governing permissions and
13
- // limitations under the License.
14
-
15
- package ledger
16
-
17
- import (
18
- "github.com/blinklabs-io/dingo/database"
19
- lcommon "github.com/blinklabs-io/gouroboros/ledger/common"
20
- )
21
-
22
- type LedgerView struct {
23
- ls *LedgerState
24
- txn *database.Txn
25
- }
26
-
27
- func (lv *LedgerView) NetworkId() uint {
28
- genesis := lv.ls.config.CardanoNodeConfig.ShelleyGenesis()
29
- if genesis == nil {
30
- // no config, definitely not mainnet
31
- return 0
32
- }
33
- networkName := genesis.NetworkId
34
- if networkName == "Mainnet" {
35
- return 1
36
- }
37
- return 0
38
- }
39
-
40
- func (lv *LedgerView) UtxoById(
41
- utxoId lcommon.TransactionInput,
42
- ) (lcommon.Utxo, error) {
43
- utxo, err := lv.ls.db.UtxoByRef(
44
- utxoId.Id().Bytes(),
45
- utxoId.Index(),
46
- lv.txn,
47
- )
48
- if err != nil {
49
- return lcommon.Utxo{}, err
50
- }
51
- tmpOutput, err := utxo.Decode()
52
- if err != nil {
53
- return lcommon.Utxo{}, err
54
- }
55
- return lcommon.Utxo{
56
- Id: utxoId,
57
- Output: tmpOutput,
58
- }, nil
59
- }
60
-
61
- func (lv *LedgerView) PoolRegistration(
62
- pkh []byte,
63
- ) ([]lcommon.PoolRegistrationCertificate, error) {
64
- poolKeyHash := lcommon.PoolKeyHash(lcommon.NewBlake2b224(pkh))
65
- return lv.ls.db.GetPoolRegistrations(poolKeyHash, lv.txn)
66
- }
67
-
68
- func (lv *LedgerView) StakeRegistration(
69
- stakingKey []byte,
70
- ) ([]lcommon.StakeRegistrationCertificate, error) {
71
- // stakingKey = lcommon.NewBlake2b224(stakingKey)
72
- return lv.ls.db.GetStakeRegistrations(stakingKey, lv.txn)
73
- }
@@ -1,50 +0,0 @@
1
- // Copyright 2024 Blink Labs Software
2
- //
3
- // Licensed under the Apache License, Version 2.0 (the "License");
4
- // you may not use this file except in compliance with the License.
5
- // You may obtain a copy of the License at
6
- //
7
- // http://www.apache.org/licenses/LICENSE-2.0
8
- //
9
- // Unless required by applicable law or agreed to in writing, software
10
- // distributed under the License is distributed on an "AS IS" BASIS,
11
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
- // See the License for the specific language governing permissions and
13
- // limitations under the License.
14
-
15
- package dingo
16
-
17
- import (
18
- olocalstatequery "github.com/blinklabs-io/gouroboros/protocol/localstatequery"
19
- )
20
-
21
- func (n *Node) localstatequeryServerConnOpts() []olocalstatequery.LocalStateQueryOptionFunc {
22
- return []olocalstatequery.LocalStateQueryOptionFunc{
23
- olocalstatequery.WithAcquireFunc(n.localstatequeryServerAcquire),
24
- olocalstatequery.WithQueryFunc(n.localstatequeryServerQuery),
25
- olocalstatequery.WithReleaseFunc(n.localstatequeryServerRelease),
26
- }
27
- }
28
-
29
- func (n *Node) localstatequeryServerAcquire(
30
- ctx olocalstatequery.CallbackContext,
31
- acquireTarget olocalstatequery.AcquireTarget,
32
- reAcquire bool,
33
- ) error {
34
- // TODO: create "view" from ledger state (#382)
35
- return nil
36
- }
37
-
38
- func (n *Node) localstatequeryServerQuery(
39
- ctx olocalstatequery.CallbackContext,
40
- query olocalstatequery.QueryWrapper,
41
- ) (any, error) {
42
- return n.ledgerState.Query(query.Query)
43
- }
44
-
45
- func (n *Node) localstatequeryServerRelease(
46
- ctx olocalstatequery.CallbackContext,
47
- ) error {
48
- // TODO: release "view" from ledger state (#382)
49
- return nil
50
- }
package/localtxmonitor.go DELETED
@@ -1,44 +0,0 @@
1
- // Copyright 2024 Blink Labs Software
2
- //
3
- // Licensed under the Apache License, Version 2.0 (the "License");
4
- // you may not use this file except in compliance with the License.
5
- // You may obtain a copy of the License at
6
- //
7
- // http://www.apache.org/licenses/LICENSE-2.0
8
- //
9
- // Unless required by applicable law or agreed to in writing, software
10
- // distributed under the License is distributed on an "AS IS" BASIS,
11
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
- // See the License for the specific language governing permissions and
13
- // limitations under the License.
14
-
15
- package dingo
16
-
17
- import (
18
- olocaltxmonitor "github.com/blinklabs-io/gouroboros/protocol/localtxmonitor"
19
- )
20
-
21
- const (
22
- localtxmonitorMempoolCapacity = 10 * 1024 * 1024 // TODO: replace with configurable value (#400)
23
- )
24
-
25
- func (n *Node) localtxmonitorServerConnOpts() []olocaltxmonitor.LocalTxMonitorOptionFunc {
26
- return []olocaltxmonitor.LocalTxMonitorOptionFunc{
27
- olocaltxmonitor.WithGetMempoolFunc(n.localtxmonitorServerGetMempool),
28
- }
29
- }
30
-
31
- func (n *Node) localtxmonitorServerGetMempool(
32
- ctx olocaltxmonitor.CallbackContext,
33
- ) (uint64, uint32, []olocaltxmonitor.TxAndEraId, error) {
34
- tip := n.ledgerState.Tip()
35
- mempoolTxs := n.mempool.Transactions()
36
- retTxs := make([]olocaltxmonitor.TxAndEraId, len(mempoolTxs))
37
- for i := 0; i < len(mempoolTxs); i++ {
38
- retTxs[i] = olocaltxmonitor.TxAndEraId{
39
- EraId: mempoolTxs[i].Type,
40
- Tx: mempoolTxs[i].Cbor,
41
- }
42
- }
43
- return tip.Point.Slot, localtxmonitorMempoolCapacity, retTxs, nil
44
- }
@@ -1,52 +0,0 @@
1
- // Copyright 2024 Blink Labs Software
2
- //
3
- // Licensed under the Apache License, Version 2.0 (the "License");
4
- // you may not use this file except in compliance with the License.
5
- // You may obtain a copy of the License at
6
- //
7
- // http://www.apache.org/licenses/LICENSE-2.0
8
- //
9
- // Unless required by applicable law or agreed to in writing, software
10
- // distributed under the License is distributed on an "AS IS" BASIS,
11
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
- // See the License for the specific language governing permissions and
13
- // limitations under the License.
14
-
15
- package dingo
16
-
17
- import (
18
- "fmt"
19
-
20
- olocaltxsubmission "github.com/blinklabs-io/gouroboros/protocol/localtxsubmission"
21
- )
22
-
23
- func (n *Node) localtxsubmissionServerConnOpts() []olocaltxsubmission.LocalTxSubmissionOptionFunc {
24
- return []olocaltxsubmission.LocalTxSubmissionOptionFunc{
25
- olocaltxsubmission.WithSubmitTxFunc(n.localtxsubmissionServerSubmitTx),
26
- }
27
- }
28
-
29
- func (n *Node) localtxsubmissionServerSubmitTx(
30
- ctx olocaltxsubmission.CallbackContext,
31
- tx olocaltxsubmission.MsgSubmitTxTransaction,
32
- ) error {
33
- // Add transaction to mempool
34
- err := n.mempool.AddTransaction(
35
- uint(tx.EraId),
36
- tx.Raw.Content.([]byte),
37
- )
38
- if err != nil {
39
- n.config.logger.Error(
40
- fmt.Sprintf(
41
- "failed to add transaction to mempool: %s",
42
- err,
43
- ),
44
- "component", "network",
45
- "protocol", "local-tx-submission",
46
- "role", "server",
47
- "connection_id", ctx.ConnectionId.String(),
48
- )
49
- return err
50
- }
51
- return nil
52
- }
@@ -1,98 +0,0 @@
1
- // Copyright 2025 Blink Labs Software
2
- //
3
- // Licensed under the Apache License, Version 2.0 (the "License");
4
- // you may not use this file except in compliance with the License.
5
- // You may obtain a copy of the License at
6
- //
7
- // http://www.apache.org/licenses/LICENSE-2.0
8
- //
9
- // Unless required by applicable law or agreed to in writing, software
10
- // distributed under the License is distributed on an "AS IS" BASIS,
11
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
- // See the License for the specific language governing permissions and
13
- // limitations under the License.
14
-
15
- package mempool
16
-
17
- import (
18
- "sync"
19
- )
20
-
21
- type MempoolConsumer struct {
22
- mempool *Mempool
23
- nextTxIdx int
24
- cache map[string]*MempoolTransaction
25
- cacheMutex sync.Mutex
26
- }
27
-
28
- func newConsumer(mempool *Mempool) *MempoolConsumer {
29
- return &MempoolConsumer{
30
- mempool: mempool,
31
- cache: make(map[string]*MempoolTransaction),
32
- }
33
- }
34
-
35
- func (m *MempoolConsumer) NextTx(blocking bool) *MempoolTransaction {
36
- if m == nil {
37
- return nil
38
- }
39
- m.mempool.RLock()
40
- defer m.mempool.RUnlock()
41
- if m.nextTxIdx >= len(m.mempool.transactions) {
42
- if !blocking {
43
- return nil
44
- }
45
- // Wait for TX to be added to mempool
46
- addTxSubId, addTxChan := m.mempool.eventBus.Subscribe(
47
- AddTransactionEventType,
48
- )
49
- m.mempool.RUnlock()
50
- <-addTxChan
51
- m.mempool.eventBus.Unsubscribe(AddTransactionEventType, addTxSubId)
52
- m.mempool.RLock()
53
- // Make sure our next TX index isn't beyond the bounds of the mempool
54
- // This shouldn't be necessary, but we probably have a bug elsewhere around
55
- // mananging the consumer nextTxId values on add/remove TX in mempool.
56
- // This is also potentially lossy in the case of multiple TXs being added to
57
- // the mempool in short succession
58
- if m.nextTxIdx >= len(m.mempool.transactions) {
59
- m.nextTxIdx = len(m.mempool.transactions) - 1
60
- }
61
- }
62
- nextTx := m.mempool.transactions[m.nextTxIdx]
63
- if nextTx != nil {
64
- // Increment next TX index
65
- m.nextTxIdx++
66
- // Add transaction to cache
67
- m.cacheMutex.Lock()
68
- m.cache[nextTx.Hash] = nextTx
69
- m.cacheMutex.Unlock()
70
- }
71
- return nextTx
72
- }
73
-
74
- func (m *MempoolConsumer) GetTxFromCache(hash string) *MempoolTransaction {
75
- if m != nil {
76
- m.cacheMutex.Lock()
77
- defer m.cacheMutex.Unlock()
78
- return m.cache[hash]
79
- }
80
- var ret *MempoolTransaction
81
- return ret
82
- }
83
-
84
- func (m *MempoolConsumer) ClearCache() {
85
- if m != nil {
86
- m.cacheMutex.Lock()
87
- defer m.cacheMutex.Unlock()
88
- m.cache = make(map[string]*MempoolTransaction)
89
- }
90
- }
91
-
92
- func (m *MempoolConsumer) RemoveTxFromCache(hash string) {
93
- if m != nil {
94
- m.cacheMutex.Lock()
95
- defer m.cacheMutex.Unlock()
96
- delete(m.cache, hash)
97
- }
98
- }
@@ -1,322 +0,0 @@
1
- // Copyright 2025 Blink Labs Software
2
- //
3
- // Licensed under the Apache License, Version 2.0 (the "License");
4
- // you may not use this file except in compliance with the License.
5
- // You may obtain a copy of the License at
6
- //
7
- // http://www.apache.org/licenses/LICENSE-2.0
8
- //
9
- // Unless required by applicable law or agreed to in writing, software
10
- // distributed under the License is distributed on an "AS IS" BASIS,
11
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
- // See the License for the specific language governing permissions and
13
- // limitations under the License.
14
-
15
- package mempool
16
-
17
- import (
18
- "io"
19
- "log/slog"
20
- "slices"
21
- "sync"
22
- "time"
23
-
24
- "github.com/blinklabs-io/dingo/chain"
25
- "github.com/blinklabs-io/dingo/event"
26
- "github.com/blinklabs-io/dingo/ledger"
27
- ouroboros "github.com/blinklabs-io/gouroboros"
28
- gledger "github.com/blinklabs-io/gouroboros/ledger"
29
- "github.com/prometheus/client_golang/prometheus"
30
- "github.com/prometheus/client_golang/prometheus/promauto"
31
- )
32
-
33
- const (
34
- AddTransactionEventType event.EventType = "mempool.add_tx"
35
- RemoveTransactionEventType event.EventType = "mempool.remove_tx"
36
- )
37
-
38
- type AddTransactionEvent struct {
39
- Hash string
40
- Body []byte
41
- Type uint
42
- }
43
-
44
- type RemoveTransactionEvent struct {
45
- Hash string
46
- }
47
-
48
- type MempoolTransaction struct {
49
- Hash string
50
- Type uint
51
- Cbor []byte
52
- LastSeen time.Time
53
- }
54
-
55
- type Mempool struct {
56
- sync.RWMutex
57
- logger *slog.Logger
58
- eventBus *event.EventBus
59
- ledgerState *ledger.LedgerState
60
- consumers map[ouroboros.ConnectionId]*MempoolConsumer
61
- consumersMutex sync.Mutex
62
- transactions []*MempoolTransaction
63
- metrics struct {
64
- txsProcessedNum prometheus.Counter
65
- txsInMempool prometheus.Gauge
66
- mempoolBytes prometheus.Gauge
67
- }
68
- }
69
-
70
- func NewMempool(
71
- logger *slog.Logger,
72
- eventBus *event.EventBus,
73
- promRegistry prometheus.Registerer,
74
- ledgerState *ledger.LedgerState,
75
- ) *Mempool {
76
- m := &Mempool{
77
- eventBus: eventBus,
78
- consumers: make(map[ouroboros.ConnectionId]*MempoolConsumer),
79
- ledgerState: ledgerState,
80
- }
81
- if logger == nil {
82
- // Create logger to throw away logs
83
- // We do this so we don't have to add guards around every log operation
84
- m.logger = slog.New(slog.NewJSONHandler(io.Discard, nil))
85
- } else {
86
- m.logger = logger
87
- }
88
- // Subscribe to chain update events
89
- go m.processChainEvents()
90
- // Init metrics
91
- promautoFactory := promauto.With(promRegistry)
92
- m.metrics.txsProcessedNum = promautoFactory.NewCounter(
93
- prometheus.CounterOpts{
94
- Name: "cardano_node_metrics_txsProcessedNum_int",
95
- Help: "total transactions processed",
96
- },
97
- )
98
- m.metrics.txsInMempool = promautoFactory.NewGauge(prometheus.GaugeOpts{
99
- Name: "cardano_node_metrics_txsInMempool_int",
100
- Help: "current count of mempool transactions",
101
- })
102
- m.metrics.mempoolBytes = promautoFactory.NewGauge(prometheus.GaugeOpts{
103
- Name: "cardano_node_metrics_mempoolBytes_int",
104
- Help: "current size of mempool transactions in bytes",
105
- })
106
- return m
107
- }
108
-
109
- func (m *Mempool) AddConsumer(connId ouroboros.ConnectionId) *MempoolConsumer {
110
- // Create consumer
111
- m.consumersMutex.Lock()
112
- defer m.consumersMutex.Unlock()
113
- consumer := newConsumer(m)
114
- m.consumers[connId] = consumer
115
- return consumer
116
- }
117
-
118
- func (m *Mempool) RemoveConsumer(connId ouroboros.ConnectionId) {
119
- m.consumersMutex.Lock()
120
- delete(m.consumers, connId)
121
- m.consumersMutex.Unlock()
122
- }
123
-
124
- func (m *Mempool) Consumer(connId ouroboros.ConnectionId) *MempoolConsumer {
125
- m.consumersMutex.Lock()
126
- defer m.consumersMutex.Unlock()
127
- return m.consumers[connId]
128
- }
129
-
130
- func (m *Mempool) processChainEvents() {
131
- chainUpdateSubId, chainUpdateChan := m.eventBus.Subscribe(
132
- chain.ChainUpdateEventType,
133
- )
134
- defer func() {
135
- m.eventBus.Unsubscribe(chain.ChainUpdateEventType, chainUpdateSubId)
136
- }()
137
- lastValidationTime := time.Now()
138
- var ok bool
139
- for {
140
- // Wait for chain event
141
- _, ok = <-chainUpdateChan
142
- if !ok {
143
- return
144
- }
145
- // Only purge once every 30 seconds when there are more blocks available
146
- if time.Since(lastValidationTime) < 30*time.Second &&
147
- len(chainUpdateChan) > 0 {
148
- continue
149
- }
150
- m.Lock()
151
- // Re-validate each TX in mempool
152
- // We iterate backward to avoid issues with shifting indexes when deleting
153
- for i := len(m.transactions) - 1; i >= 0; i-- {
154
- tx := m.transactions[i]
155
- // Decode transaction
156
- tmpTx, err := gledger.NewTransactionFromCbor(tx.Type, tx.Cbor)
157
- if err != nil {
158
- m.removeTransactionByIndex(i)
159
- m.logger.Error(
160
- "removed transaction after decode failure",
161
- "component", "mempool",
162
- "tx_hash", tx.Hash,
163
- "error", err,
164
- )
165
- continue
166
- }
167
- // Validate transaction
168
- if err := m.ledgerState.ValidateTx(tmpTx); err != nil {
169
- m.removeTransactionByIndex(i)
170
- m.logger.Debug(
171
- "removed transaction after re-validation failure",
172
- "component", "mempool",
173
- "tx_hash", tx.Hash,
174
- "error", err,
175
- )
176
- }
177
- }
178
- m.Unlock()
179
- }
180
- }
181
-
182
- func (m *Mempool) AddTransaction(txType uint, txBytes []byte) error {
183
- // Decode transaction
184
- tmpTx, err := gledger.NewTransactionFromCbor(txType, txBytes)
185
- if err != nil {
186
- return err
187
- }
188
- // Validate transaction
189
- if err := m.ledgerState.ValidateTx(tmpTx); err != nil {
190
- return err
191
- }
192
- // Build mempool entry
193
- txHash := tmpTx.Hash().String()
194
- tx := MempoolTransaction{
195
- Hash: txHash,
196
- Type: txType,
197
- Cbor: txBytes,
198
- LastSeen: time.Now(),
199
- }
200
- m.Lock()
201
- m.consumersMutex.Lock()
202
- defer func() {
203
- m.consumersMutex.Unlock()
204
- m.Unlock()
205
- }()
206
- // Update last seen for existing TX
207
- existingTx := m.getTransaction(tx.Hash)
208
- if existingTx != nil {
209
- tx.LastSeen = time.Now()
210
- m.logger.Debug(
211
- "updated last seen for transaction",
212
- "component", "mempool",
213
- "tx_hash", tx.Hash,
214
- )
215
- return nil
216
- }
217
- // Add transaction record
218
- m.transactions = append(m.transactions, &tx)
219
- m.logger.Debug(
220
- "added transaction",
221
- "component", "mempool",
222
- "tx_hash", tx.Hash,
223
- )
224
- m.metrics.txsProcessedNum.Inc()
225
- m.metrics.txsInMempool.Inc()
226
- m.metrics.mempoolBytes.Add(float64(len(tx.Cbor)))
227
- // Generate event
228
- m.eventBus.Publish(
229
- AddTransactionEventType,
230
- event.NewEvent(
231
- AddTransactionEventType,
232
- AddTransactionEvent{
233
- Hash: tx.Hash,
234
- Type: tx.Type,
235
- Body: tx.Cbor[:],
236
- },
237
- ),
238
- )
239
- return nil
240
- }
241
-
242
- func (m *Mempool) GetTransaction(txHash string) (MempoolTransaction, bool) {
243
- m.Lock()
244
- defer m.Unlock()
245
- ret := m.getTransaction(txHash)
246
- if ret == nil {
247
- return MempoolTransaction{}, false
248
- }
249
- return *ret, true
250
- }
251
-
252
- func (m *Mempool) Transactions() []MempoolTransaction {
253
- m.Lock()
254
- defer m.Unlock()
255
- ret := make([]MempoolTransaction, len(m.transactions))
256
- for i := 0; i < len(m.transactions); i++ {
257
- ret[i] = *m.transactions[i]
258
- }
259
- return ret
260
- }
261
-
262
- func (m *Mempool) getTransaction(txHash string) *MempoolTransaction {
263
- for _, tx := range m.transactions {
264
- if tx.Hash == txHash {
265
- return tx
266
- }
267
- }
268
- return nil
269
- }
270
-
271
- func (m *Mempool) RemoveTransaction(txHash string) {
272
- m.Lock()
273
- defer m.Unlock()
274
- if m.removeTransaction(txHash) {
275
- m.logger.Debug(
276
- "removed transaction",
277
- "component", "mempool",
278
- "tx_hash", txHash,
279
- )
280
- }
281
- }
282
-
283
- func (m *Mempool) removeTransaction(txHash string) bool {
284
- for txIdx, tx := range m.transactions {
285
- if tx.Hash == txHash {
286
- return m.removeTransactionByIndex(txIdx)
287
- }
288
- }
289
- return false
290
- }
291
-
292
- func (m *Mempool) removeTransactionByIndex(txIdx int) bool {
293
- if txIdx >= len(m.transactions) {
294
- return false
295
- }
296
- tx := m.transactions[txIdx]
297
- m.transactions = slices.Delete(
298
- m.transactions,
299
- txIdx,
300
- txIdx+1,
301
- )
302
- m.metrics.txsInMempool.Dec()
303
- m.metrics.mempoolBytes.Sub(float64(len(tx.Cbor)))
304
- // Update consumer indexes to reflect removed TX
305
- for _, consumer := range m.consumers {
306
- // Decrement consumer index if the consumer has reached the removed TX
307
- if consumer.nextTxIdx > txIdx {
308
- consumer.nextTxIdx--
309
- }
310
- }
311
- // Generate event
312
- m.eventBus.Publish(
313
- RemoveTransactionEventType,
314
- event.NewEvent(
315
- RemoveTransactionEventType,
316
- RemoveTransactionEvent{
317
- Hash: tx.Hash,
318
- },
319
- ),
320
- )
321
- return true
322
- }