@blinklabs/dingo 0.7.0 → 0.8.1
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.
- package/README.md +2 -1
- package/{bin/dingo → dingo} +0 -0
- package/dingo.yaml.example +53 -0
- package/package.json +2 -2
- package/.github/CODEOWNERS +0 -5
- package/.github/assets/dingo-ate-my-blockchain.png +0 -0
- package/.github/assets/dingo-illustration.png +0 -0
- package/.github/assets/dingo-logo-with-text-horizontal.png +0 -0
- package/.github/assets/dingo-logo-with-text.png +0 -0
- package/.github/dependabot.yml +0 -19
- package/.github/dingo-20241210.png +0 -0
- package/.github/dingo.md +0 -56
- package/.github/workflows/ci-docker.yml +0 -36
- package/.github/workflows/conventional-commits.yml +0 -17
- package/.github/workflows/go-test.yml +0 -29
- package/.github/workflows/golangci-lint.yml +0 -23
- package/.github/workflows/publish.yml +0 -207
- package/Dockerfile +0 -25
- package/Makefile +0 -53
- package/blockfetch.go +0 -144
- package/chain/chain.go +0 -504
- package/chain/chain_test.go +0 -468
- package/chain/errors.go +0 -80
- package/chain/event.go +0 -33
- package/chain/iter.go +0 -64
- package/chainsync/chainsync.go +0 -97
- package/chainsync.go +0 -223
- package/cmd/dingo/load.go +0 -52
- package/cmd/dingo/main.go +0 -118
- package/cmd/dingo/serve.go +0 -49
- package/config/cardano/node.go +0 -192
- package/config/cardano/node_test.go +0 -85
- package/config/cardano/preview/README.md +0 -4
- package/config/cardano/preview/alonzo-genesis.json +0 -196
- package/config/cardano/preview/byron-genesis.json +0 -117
- package/config/cardano/preview/config.json +0 -114
- package/config/cardano/preview/conway-genesis.json +0 -297
- package/config/cardano/preview/shelley-genesis.json +0 -68
- package/config.go +0 -245
- package/connmanager/connection_manager.go +0 -105
- package/connmanager/connection_manager_test.go +0 -185
- package/connmanager/event.go +0 -37
- package/connmanager/listener.go +0 -140
- package/connmanager/outbound.go +0 -93
- package/connmanager/socket.go +0 -55
- package/connmanager/unix.go +0 -78
- package/custom-p2p-topology.json +0 -24
- package/custom-p2p-topology.json.backup +0 -24
- package/custom-p2p-topology.json.mainnet +0 -37
- package/database/account.go +0 -180
- package/database/block.go +0 -362
- package/database/certs.go +0 -53
- package/database/commit_timestamp.go +0 -77
- package/database/database.go +0 -118
- package/database/database_test.go +0 -62
- package/database/drep.go +0 -47
- package/database/epoch.go +0 -121
- package/database/immutable/chunk.go +0 -182
- package/database/immutable/immutable.go +0 -350
- package/database/immutable/immutable_test.go +0 -59
- package/database/immutable/primary.go +0 -106
- package/database/immutable/secondary.go +0 -103
- package/database/immutable/testdata/08893.chunk +0 -0
- package/database/immutable/testdata/08893.primary +0 -0
- package/database/immutable/testdata/08893.secondary +0 -0
- package/database/immutable/testdata/08894.chunk +0 -0
- package/database/immutable/testdata/08894.primary +0 -0
- package/database/immutable/testdata/08894.secondary +0 -0
- package/database/immutable/testdata/README.md +0 -4
- package/database/plugin/blob/badger/commit_timestamp.go +0 -50
- package/database/plugin/blob/badger/database.go +0 -152
- package/database/plugin/blob/badger/logger.go +0 -63
- package/database/plugin/blob/badger/metrics.go +0 -98
- package/database/plugin/blob/blob.go +0 -19
- package/database/plugin/blob/store.go +0 -40
- package/database/plugin/log.go +0 -27
- package/database/plugin/metadata/metadata.go +0 -19
- package/database/plugin/metadata/sqlite/account.go +0 -313
- package/database/plugin/metadata/sqlite/certs.go +0 -58
- package/database/plugin/metadata/sqlite/commit_timestamp.go +0 -68
- package/database/plugin/metadata/sqlite/database.go +0 -218
- package/database/plugin/metadata/sqlite/drep.go +0 -140
- package/database/plugin/metadata/sqlite/epoch.go +0 -120
- package/database/plugin/metadata/sqlite/models/account.go +0 -118
- package/database/plugin/metadata/sqlite/models/auth_committee_hot.go +0 -26
- package/database/plugin/metadata/sqlite/models/drep.go +0 -52
- package/database/plugin/metadata/sqlite/models/epoch.go +0 -31
- package/database/plugin/metadata/sqlite/models/models.go +0 -46
- package/database/plugin/metadata/sqlite/models/pool.go +0 -97
- package/database/plugin/metadata/sqlite/models/pparam_update.go +0 -27
- package/database/plugin/metadata/sqlite/models/pparams.go +0 -27
- package/database/plugin/metadata/sqlite/models/resign_committee_cold.go +0 -27
- package/database/plugin/metadata/sqlite/models/stake_vote_delegation.go +0 -27
- package/database/plugin/metadata/sqlite/models/tip.go +0 -26
- package/database/plugin/metadata/sqlite/models/update_drep.go +0 -27
- package/database/plugin/metadata/sqlite/models/utxo.go +0 -30
- package/database/plugin/metadata/sqlite/models/vote_delegation.go +0 -26
- package/database/plugin/metadata/sqlite/models/vote_registration_delegation.go +0 -15
- package/database/plugin/metadata/sqlite/pool.go +0 -240
- package/database/plugin/metadata/sqlite/pparams.go +0 -110
- package/database/plugin/metadata/sqlite/tip.go +0 -83
- package/database/plugin/metadata/sqlite/utxo.go +0 -292
- package/database/plugin/metadata/store.go +0 -198
- package/database/plugin/option.go +0 -190
- package/database/plugin/plugin.go +0 -20
- package/database/plugin/register.go +0 -118
- package/database/pparams.go +0 -145
- package/database/tip.go +0 -45
- package/database/txn.go +0 -147
- package/database/types/types.go +0 -74
- package/database/types/types_test.go +0 -83
- package/database/utxo.go +0 -263
- package/dist/artifacts.json +0 -1
- package/dist/checksums.txt +0 -22
- package/dist/config.yaml +0 -253
- package/dist/dingo-0.5.0-SNAPSHOT-d9431e4.tar.gz +0 -0
- package/dist/dingo-0.5.0-SNAPSHOT-d9431e4.tar.gz.sbom.json +0 -1
- package/dist/dingo_0.5.0-SNAPSHOT-d9431e4_darwin_arm64.tar.gz +0 -0
- package/dist/dingo_0.5.0-SNAPSHOT-d9431e4_darwin_arm64.tar.gz.sbom.json +0 -1
- package/dist/dingo_0.5.0-SNAPSHOT-d9431e4_darwin_x86_64.tar.gz +0 -0
- package/dist/dingo_0.5.0-SNAPSHOT-d9431e4_darwin_x86_64.tar.gz.sbom.json +0 -1
- package/dist/dingo_0.5.0-SNAPSHOT-d9431e4_linux_amd64.apk +0 -0
- package/dist/dingo_0.5.0-SNAPSHOT-d9431e4_linux_amd64.apk.sbom.json +0 -1
- package/dist/dingo_0.5.0-SNAPSHOT-d9431e4_linux_amd64.deb +0 -0
- package/dist/dingo_0.5.0-SNAPSHOT-d9431e4_linux_amd64.deb.sbom.json +0 -1
- package/dist/dingo_0.5.0-SNAPSHOT-d9431e4_linux_amd64.rpm +0 -0
- package/dist/dingo_0.5.0-SNAPSHOT-d9431e4_linux_amd64.rpm.sbom.json +0 -1
- package/dist/dingo_0.5.0-SNAPSHOT-d9431e4_linux_arm64.apk +0 -0
- package/dist/dingo_0.5.0-SNAPSHOT-d9431e4_linux_arm64.apk.sbom.json +0 -1
- package/dist/dingo_0.5.0-SNAPSHOT-d9431e4_linux_arm64.deb +0 -0
- package/dist/dingo_0.5.0-SNAPSHOT-d9431e4_linux_arm64.deb.sbom.json +0 -1
- package/dist/dingo_0.5.0-SNAPSHOT-d9431e4_linux_arm64.rpm +0 -0
- package/dist/dingo_0.5.0-SNAPSHOT-d9431e4_linux_arm64.rpm.sbom.json +0 -1
- package/dist/dingo_0.5.0-SNAPSHOT-d9431e4_linux_arm64.tar.gz +0 -0
- package/dist/dingo_0.5.0-SNAPSHOT-d9431e4_linux_arm64.tar.gz.sbom.json +0 -1
- package/dist/dingo_0.5.0-SNAPSHOT-d9431e4_linux_x86_64.tar.gz +0 -0
- package/dist/dingo_0.5.0-SNAPSHOT-d9431e4_linux_x86_64.tar.gz.sbom.json +0 -1
- package/dist/dingo_darwin_amd64_v1/dingo +0 -0
- package/dist/dingo_darwin_arm64_v8.0/dingo +0 -0
- package/dist/dingo_linux_amd64_v1/dingo +0 -0
- package/dist/dingo_linux_arm64_v8.0/dingo +0 -0
- package/dist/homebrew/dingo.rb +0 -51
- package/dist/metadata.json +0 -1
- package/event/event.go +0 -141
- package/event/event_test.go +0 -115
- package/event/metrics.go +0 -44
- package/go.mod +0 -98
- package/go.sum +0 -358
- package/internal/config/config.go +0 -145
- package/internal/config/config_test.go +0 -118
- package/internal/node/load.go +0 -149
- package/internal/node/node.go +0 -176
- package/internal/version/version.go +0 -33
- package/ledger/certs.go +0 -164
- package/ledger/chainsync.go +0 -504
- package/ledger/delta.go +0 -99
- package/ledger/eras/allegra.go +0 -154
- package/ledger/eras/alonzo.go +0 -156
- package/ledger/eras/babbage.go +0 -154
- package/ledger/eras/byron.go +0 -42
- package/ledger/eras/conway.go +0 -166
- package/ledger/eras/eras.go +0 -44
- package/ledger/eras/mary.go +0 -154
- package/ledger/eras/shelley.go +0 -164
- package/ledger/error.go +0 -19
- package/ledger/event.go +0 -50
- package/ledger/metrics.go +0 -53
- package/ledger/queries.go +0 -258
- package/ledger/slot.go +0 -127
- package/ledger/slot_test.go +0 -147
- package/ledger/state.go +0 -821
- package/ledger/view.go +0 -73
- package/localstatequery.go +0 -50
- package/localtxmonitor.go +0 -44
- package/localtxsubmission.go +0 -52
- package/mempool/consumer.go +0 -98
- package/mempool/mempool.go +0 -322
- package/node.go +0 -320
- package/peergov/event.go +0 -27
- package/peergov/peer.go +0 -67
- package/peergov/peergov.go +0 -290
- package/peersharing.go +0 -70
- package/preview-local-topology.json +0 -23
- package/topology/topology.go +0 -69
- package/topology/topology_test.go +0 -179
- package/tracing.go +0 -65
- package/txsubmission.go +0 -233
- package/utxorpc/query.go +0 -311
- package/utxorpc/submit.go +0 -395
- package/utxorpc/sync.go +0 -276
- package/utxorpc/utxorpc.go +0 -166
- package/utxorpc/watch.go +0 -310
package/ledger/certs.go
DELETED
|
@@ -1,164 +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
|
-
"fmt"
|
|
19
|
-
|
|
20
|
-
"github.com/blinklabs-io/dingo/database"
|
|
21
|
-
"github.com/blinklabs-io/gouroboros/ledger"
|
|
22
|
-
lcommon "github.com/blinklabs-io/gouroboros/ledger/common"
|
|
23
|
-
pcommon "github.com/blinklabs-io/gouroboros/protocol/common"
|
|
24
|
-
)
|
|
25
|
-
|
|
26
|
-
func (ls *LedgerState) processTransactionCertificates(
|
|
27
|
-
txn *database.Txn,
|
|
28
|
-
blockPoint pcommon.Point,
|
|
29
|
-
certs []ledger.Certificate,
|
|
30
|
-
) error {
|
|
31
|
-
var tmpCert lcommon.Certificate
|
|
32
|
-
for _, tmpCert = range certs {
|
|
33
|
-
certDeposit, err := ls.currentEra.CertDepositFunc(
|
|
34
|
-
tmpCert,
|
|
35
|
-
ls.currentPParams,
|
|
36
|
-
)
|
|
37
|
-
if err != nil {
|
|
38
|
-
return err
|
|
39
|
-
}
|
|
40
|
-
switch cert := tmpCert.(type) {
|
|
41
|
-
case *lcommon.DeregistrationCertificate:
|
|
42
|
-
err := ls.db.SetDeregistration(
|
|
43
|
-
cert,
|
|
44
|
-
blockPoint.Slot,
|
|
45
|
-
txn,
|
|
46
|
-
)
|
|
47
|
-
if err != nil {
|
|
48
|
-
return err
|
|
49
|
-
}
|
|
50
|
-
case *lcommon.DeregistrationDrepCertificate:
|
|
51
|
-
err := ls.db.SetDeregistrationDrep(
|
|
52
|
-
cert,
|
|
53
|
-
blockPoint.Slot,
|
|
54
|
-
certDeposit,
|
|
55
|
-
txn,
|
|
56
|
-
)
|
|
57
|
-
if err != nil {
|
|
58
|
-
return err
|
|
59
|
-
}
|
|
60
|
-
case *lcommon.PoolRegistrationCertificate:
|
|
61
|
-
err := ls.db.SetPoolRegistration(
|
|
62
|
-
cert,
|
|
63
|
-
blockPoint.Slot,
|
|
64
|
-
certDeposit,
|
|
65
|
-
txn,
|
|
66
|
-
)
|
|
67
|
-
if err != nil {
|
|
68
|
-
return err
|
|
69
|
-
}
|
|
70
|
-
case *lcommon.PoolRetirementCertificate:
|
|
71
|
-
err := ls.db.SetPoolRetirement(
|
|
72
|
-
cert,
|
|
73
|
-
blockPoint.Slot,
|
|
74
|
-
txn,
|
|
75
|
-
)
|
|
76
|
-
if err != nil {
|
|
77
|
-
return err
|
|
78
|
-
}
|
|
79
|
-
case *lcommon.RegistrationCertificate:
|
|
80
|
-
err := ls.db.SetRegistration(
|
|
81
|
-
cert,
|
|
82
|
-
blockPoint.Slot,
|
|
83
|
-
certDeposit,
|
|
84
|
-
txn,
|
|
85
|
-
)
|
|
86
|
-
if err != nil {
|
|
87
|
-
return err
|
|
88
|
-
}
|
|
89
|
-
case *lcommon.RegistrationDrepCertificate:
|
|
90
|
-
err := ls.db.SetRegistrationDrep(
|
|
91
|
-
cert,
|
|
92
|
-
blockPoint.Slot,
|
|
93
|
-
certDeposit,
|
|
94
|
-
txn,
|
|
95
|
-
)
|
|
96
|
-
if err != nil {
|
|
97
|
-
return err
|
|
98
|
-
}
|
|
99
|
-
case *lcommon.StakeDelegationCertificate:
|
|
100
|
-
err := ls.db.SetStakeDelegation(
|
|
101
|
-
cert,
|
|
102
|
-
blockPoint.Slot,
|
|
103
|
-
txn,
|
|
104
|
-
)
|
|
105
|
-
if err != nil {
|
|
106
|
-
return err
|
|
107
|
-
}
|
|
108
|
-
case *lcommon.StakeDeregistrationCertificate:
|
|
109
|
-
err := ls.db.SetStakeDeregistration(
|
|
110
|
-
cert,
|
|
111
|
-
blockPoint.Slot,
|
|
112
|
-
txn,
|
|
113
|
-
)
|
|
114
|
-
if err != nil {
|
|
115
|
-
return err
|
|
116
|
-
}
|
|
117
|
-
case *lcommon.StakeRegistrationCertificate:
|
|
118
|
-
err := ls.db.SetStakeRegistration(
|
|
119
|
-
cert,
|
|
120
|
-
blockPoint.Slot,
|
|
121
|
-
certDeposit,
|
|
122
|
-
txn,
|
|
123
|
-
)
|
|
124
|
-
if err != nil {
|
|
125
|
-
return err
|
|
126
|
-
}
|
|
127
|
-
case *lcommon.StakeRegistrationDelegationCertificate:
|
|
128
|
-
err := ls.db.SetStakeRegistrationDelegation(
|
|
129
|
-
cert,
|
|
130
|
-
blockPoint.Slot,
|
|
131
|
-
certDeposit,
|
|
132
|
-
txn,
|
|
133
|
-
)
|
|
134
|
-
if err != nil {
|
|
135
|
-
return err
|
|
136
|
-
}
|
|
137
|
-
case *lcommon.StakeVoteRegistrationDelegationCertificate:
|
|
138
|
-
err := ls.db.SetStakeVoteRegistrationDelegation(
|
|
139
|
-
cert,
|
|
140
|
-
blockPoint.Slot,
|
|
141
|
-
certDeposit,
|
|
142
|
-
txn,
|
|
143
|
-
)
|
|
144
|
-
if err != nil {
|
|
145
|
-
return err
|
|
146
|
-
}
|
|
147
|
-
case *lcommon.VoteRegistrationDelegationCertificate:
|
|
148
|
-
err := ls.db.SetVoteRegistrationDelegation(
|
|
149
|
-
cert,
|
|
150
|
-
blockPoint.Slot,
|
|
151
|
-
certDeposit,
|
|
152
|
-
txn,
|
|
153
|
-
)
|
|
154
|
-
if err != nil {
|
|
155
|
-
return err
|
|
156
|
-
}
|
|
157
|
-
default:
|
|
158
|
-
ls.config.Logger.Warn(
|
|
159
|
-
fmt.Sprintf("ignoring unsupported certificate type %T", cert),
|
|
160
|
-
)
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
return nil
|
|
164
|
-
}
|
package/ledger/chainsync.go
DELETED
|
@@ -1,504 +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
|
-
"encoding/hex"
|
|
19
|
-
"errors"
|
|
20
|
-
"fmt"
|
|
21
|
-
"math/big"
|
|
22
|
-
"slices"
|
|
23
|
-
"time"
|
|
24
|
-
|
|
25
|
-
"github.com/blinklabs-io/dingo/chain"
|
|
26
|
-
"github.com/blinklabs-io/dingo/database"
|
|
27
|
-
"github.com/blinklabs-io/dingo/event"
|
|
28
|
-
"github.com/blinklabs-io/dingo/ledger/eras"
|
|
29
|
-
ouroboros "github.com/blinklabs-io/gouroboros"
|
|
30
|
-
"github.com/blinklabs-io/gouroboros/cbor"
|
|
31
|
-
lcommon "github.com/blinklabs-io/gouroboros/ledger/common"
|
|
32
|
-
ocommon "github.com/blinklabs-io/gouroboros/protocol/common"
|
|
33
|
-
)
|
|
34
|
-
|
|
35
|
-
const (
|
|
36
|
-
// Max number of blocks to fetch in a single blockfetch call
|
|
37
|
-
// This prevents us exceeding the configured recv queue size in the block-fetch protocol
|
|
38
|
-
blockfetchBatchSize = 500
|
|
39
|
-
|
|
40
|
-
// TODO: calculate from protocol params
|
|
41
|
-
// Number of slots from upstream tip to stop doing blockfetch batches
|
|
42
|
-
blockfetchBatchSlotThreshold = 2500 * 20
|
|
43
|
-
|
|
44
|
-
// Timeout for updates on a blockfetch operation. This is based on a 2s BatchStart
|
|
45
|
-
// and a 2s Block timeout for blockfetch
|
|
46
|
-
blockfetchBusyTimeout = 5 * time.Second
|
|
47
|
-
)
|
|
48
|
-
|
|
49
|
-
func (ls *LedgerState) handleEventChainsync(evt event.Event) {
|
|
50
|
-
ls.chainsyncMutex.Lock()
|
|
51
|
-
defer ls.chainsyncMutex.Unlock()
|
|
52
|
-
e := evt.Data.(ChainsyncEvent)
|
|
53
|
-
if e.Rollback {
|
|
54
|
-
if err := ls.handleEventChainsyncRollback(e); err != nil {
|
|
55
|
-
// TODO: actually handle this error
|
|
56
|
-
ls.config.Logger.Error(
|
|
57
|
-
"failed to handle rollback",
|
|
58
|
-
"component", "ledger",
|
|
59
|
-
"error", err,
|
|
60
|
-
)
|
|
61
|
-
return
|
|
62
|
-
}
|
|
63
|
-
} else if e.BlockHeader != nil {
|
|
64
|
-
if err := ls.handleEventChainsyncBlockHeader(e); err != nil {
|
|
65
|
-
// TODO: actually handle this error
|
|
66
|
-
ls.config.Logger.Error(
|
|
67
|
-
fmt.Sprintf("ledger: failed to handle block header: %s", err),
|
|
68
|
-
)
|
|
69
|
-
return
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
func (ls *LedgerState) handleEventBlockfetch(evt event.Event) {
|
|
75
|
-
ls.chainsyncBlockfetchMutex.Lock()
|
|
76
|
-
defer ls.chainsyncBlockfetchMutex.Unlock()
|
|
77
|
-
e := evt.Data.(BlockfetchEvent)
|
|
78
|
-
if e.BatchDone {
|
|
79
|
-
if err := ls.handleEventBlockfetchBatchDone(e); err != nil {
|
|
80
|
-
// TODO: actually handle this error
|
|
81
|
-
ls.config.Logger.Error(
|
|
82
|
-
fmt.Sprintf(
|
|
83
|
-
"ledger: failed to handle blockfetch batch done: %s",
|
|
84
|
-
err,
|
|
85
|
-
),
|
|
86
|
-
)
|
|
87
|
-
}
|
|
88
|
-
} else if e.Block != nil {
|
|
89
|
-
if err := ls.handleEventBlockfetchBlock(e); err != nil {
|
|
90
|
-
// TODO: actually handle this error
|
|
91
|
-
ls.config.Logger.Error(
|
|
92
|
-
fmt.Sprintf("ledger: failed to handle block: %s", err),
|
|
93
|
-
)
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
func (ls *LedgerState) handleEventChainsyncRollback(e ChainsyncEvent) error {
|
|
99
|
-
if err := ls.chain.Rollback(e.Point); err != nil {
|
|
100
|
-
return fmt.Errorf("chain rollback failed: %w", err)
|
|
101
|
-
}
|
|
102
|
-
return nil
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
func (ls *LedgerState) handleEventChainsyncBlockHeader(e ChainsyncEvent) error {
|
|
106
|
-
// Allow us to build up a few blockfetch batches worth of headers
|
|
107
|
-
allowedHeaderCount := blockfetchBatchSize * 4
|
|
108
|
-
headerCount := ls.chain.HeaderCount()
|
|
109
|
-
// Wait for current blockfetch batch to finish before we collect more block headers
|
|
110
|
-
if headerCount >= allowedHeaderCount {
|
|
111
|
-
// We assign the channel to a temp var to protect against trying to read from a nil channel
|
|
112
|
-
// without a race condition
|
|
113
|
-
tmpDoneChan := ls.chainsyncBlockfetchDoneChan
|
|
114
|
-
if tmpDoneChan != nil {
|
|
115
|
-
<-tmpDoneChan
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
// Add header to chain
|
|
119
|
-
if err := ls.chain.AddBlockHeader(e.BlockHeader); err != nil {
|
|
120
|
-
if !errors.As(err, &chain.BlockNotFitChainTipError{}) {
|
|
121
|
-
return fmt.Errorf("failed adding chain block header: %w", err)
|
|
122
|
-
}
|
|
123
|
-
ls.config.Logger.Warn(
|
|
124
|
-
fmt.Sprintf(
|
|
125
|
-
"ignoring chainsync block header: %s",
|
|
126
|
-
err,
|
|
127
|
-
),
|
|
128
|
-
)
|
|
129
|
-
return nil
|
|
130
|
-
}
|
|
131
|
-
// Wait for additional block headers before fetching block bodies if we're
|
|
132
|
-
// far enough out from upstream tip
|
|
133
|
-
if e.Point.Slot < e.Tip.Point.Slot &&
|
|
134
|
-
(e.Tip.Point.Slot-e.Point.Slot > blockfetchBatchSlotThreshold) &&
|
|
135
|
-
(headerCount+1) < allowedHeaderCount {
|
|
136
|
-
return nil
|
|
137
|
-
}
|
|
138
|
-
// We use the blockfetch lock to ensure we aren't starting a batch at the same
|
|
139
|
-
// time as blockfetch starts a new one to avoid deadlocks
|
|
140
|
-
ls.chainsyncBlockfetchMutex.Lock()
|
|
141
|
-
defer ls.chainsyncBlockfetchMutex.Unlock()
|
|
142
|
-
// Don't start fetch if there's already one in progress
|
|
143
|
-
if ls.chainsyncBlockfetchDoneChan != nil {
|
|
144
|
-
// Clear blockfetch busy flag on timeout
|
|
145
|
-
if time.Since(ls.chainsyncBlockfetchBusyTime) > blockfetchBusyTimeout {
|
|
146
|
-
ls.blockfetchRequestRangeCleanup(true)
|
|
147
|
-
ls.config.Logger.Warn(
|
|
148
|
-
fmt.Sprintf(
|
|
149
|
-
"blockfetch operation timed out after %s",
|
|
150
|
-
blockfetchBusyTimeout,
|
|
151
|
-
),
|
|
152
|
-
"component",
|
|
153
|
-
"ledger",
|
|
154
|
-
)
|
|
155
|
-
return nil
|
|
156
|
-
}
|
|
157
|
-
ls.chainsyncBlockfetchWaiting = true
|
|
158
|
-
return nil
|
|
159
|
-
}
|
|
160
|
-
// Request next bulk range
|
|
161
|
-
headerStart, headerEnd := ls.chain.HeaderRange(blockfetchBatchSize)
|
|
162
|
-
err := ls.blockfetchRequestRangeStart(
|
|
163
|
-
e.ConnectionId,
|
|
164
|
-
headerStart,
|
|
165
|
-
headerEnd,
|
|
166
|
-
)
|
|
167
|
-
if err != nil {
|
|
168
|
-
ls.blockfetchRequestRangeCleanup(true)
|
|
169
|
-
return err
|
|
170
|
-
}
|
|
171
|
-
ls.chainsyncBlockfetchBusyTime = time.Now()
|
|
172
|
-
return nil
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
//nolint:unparam
|
|
176
|
-
func (ls *LedgerState) handleEventBlockfetchBlock(e BlockfetchEvent) error {
|
|
177
|
-
ls.chainsyncBlockEvents = append(
|
|
178
|
-
ls.chainsyncBlockEvents,
|
|
179
|
-
e,
|
|
180
|
-
)
|
|
181
|
-
// Update busy time in order to detect fetch timeout
|
|
182
|
-
ls.chainsyncBlockfetchBusyTime = time.Now()
|
|
183
|
-
return nil
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
func (ls *LedgerState) processBlockEvents() error {
|
|
187
|
-
batchOffset := 0
|
|
188
|
-
for {
|
|
189
|
-
batchSize := min(
|
|
190
|
-
10, // Chosen to stay well under badger transaction size limit
|
|
191
|
-
len(ls.chainsyncBlockEvents)-batchOffset,
|
|
192
|
-
)
|
|
193
|
-
if batchSize <= 0 {
|
|
194
|
-
break
|
|
195
|
-
}
|
|
196
|
-
ls.Lock()
|
|
197
|
-
// Start a transaction
|
|
198
|
-
txn := ls.db.BlobTxn(true)
|
|
199
|
-
err := txn.Do(func(txn *database.Txn) error {
|
|
200
|
-
for _, evt := range ls.chainsyncBlockEvents[batchOffset : batchOffset+batchSize] {
|
|
201
|
-
if err := ls.processBlockEvent(txn, evt); err != nil {
|
|
202
|
-
return fmt.Errorf("failed processing block event: %w", err)
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
return nil
|
|
206
|
-
})
|
|
207
|
-
ls.Unlock()
|
|
208
|
-
if err != nil {
|
|
209
|
-
return err
|
|
210
|
-
}
|
|
211
|
-
batchOffset += batchSize
|
|
212
|
-
}
|
|
213
|
-
ls.chainsyncBlockEvents = nil
|
|
214
|
-
return nil
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
func (ls *LedgerState) createGenesisBlock() error {
|
|
218
|
-
if ls.currentEpoch.SlotLength > 0 {
|
|
219
|
-
return nil
|
|
220
|
-
}
|
|
221
|
-
txn := ls.db.Transaction(true)
|
|
222
|
-
err := txn.Do(func(txn *database.Txn) error {
|
|
223
|
-
// Record genesis UTxOs
|
|
224
|
-
byronGenesis := ls.config.CardanoNodeConfig.ByronGenesis()
|
|
225
|
-
genesisUtxos, err := byronGenesis.GenesisUtxos()
|
|
226
|
-
if err != nil {
|
|
227
|
-
return fmt.Errorf("failed to generate genesis UTxOs: %w", err)
|
|
228
|
-
}
|
|
229
|
-
for _, utxo := range genesisUtxos {
|
|
230
|
-
outAddr := utxo.Output.Address()
|
|
231
|
-
outputCbor, err := cbor.Encode(utxo.Output)
|
|
232
|
-
if err != nil {
|
|
233
|
-
return fmt.Errorf("encode UTxO: %w", err)
|
|
234
|
-
}
|
|
235
|
-
err = ls.db.NewUtxo(
|
|
236
|
-
utxo.Id.Id().Bytes(),
|
|
237
|
-
utxo.Id.Index(),
|
|
238
|
-
0,
|
|
239
|
-
outAddr.PaymentKeyHash().Bytes(),
|
|
240
|
-
outAddr.StakeKeyHash().Bytes(),
|
|
241
|
-
outputCbor,
|
|
242
|
-
txn,
|
|
243
|
-
)
|
|
244
|
-
if err != nil {
|
|
245
|
-
return fmt.Errorf("add genesis UTxO: %w", err)
|
|
246
|
-
}
|
|
247
|
-
}
|
|
248
|
-
return nil
|
|
249
|
-
})
|
|
250
|
-
return err
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
func (ls *LedgerState) calculateEpochNonce(
|
|
254
|
-
txn *database.Txn,
|
|
255
|
-
epochStartSlot uint64,
|
|
256
|
-
) ([]byte, error) {
|
|
257
|
-
// No epoch nonce in Byron
|
|
258
|
-
if ls.currentEra.Id == 0 {
|
|
259
|
-
return nil, nil
|
|
260
|
-
}
|
|
261
|
-
// Use Shelley genesis hash for initial epoch nonce
|
|
262
|
-
if len(ls.currentEpoch.Nonce) == 0 {
|
|
263
|
-
genesisHashBytes, err := hex.DecodeString(
|
|
264
|
-
ls.config.CardanoNodeConfig.ShelleyGenesisHash,
|
|
265
|
-
)
|
|
266
|
-
if err != nil {
|
|
267
|
-
return nil, fmt.Errorf("decode genesis hash: %w", err)
|
|
268
|
-
}
|
|
269
|
-
return genesisHashBytes, nil
|
|
270
|
-
}
|
|
271
|
-
// Calculate stability window
|
|
272
|
-
byronGenesis := ls.config.CardanoNodeConfig.ByronGenesis()
|
|
273
|
-
shelleyGenesis := ls.config.CardanoNodeConfig.ShelleyGenesis()
|
|
274
|
-
if byronGenesis == nil || shelleyGenesis == nil {
|
|
275
|
-
return nil, errors.New("could not get genesis config")
|
|
276
|
-
}
|
|
277
|
-
stabilityWindow := new(big.Rat).Quo(
|
|
278
|
-
big.NewRat(
|
|
279
|
-
int64(3*byronGenesis.ProtocolConsts.K),
|
|
280
|
-
1,
|
|
281
|
-
),
|
|
282
|
-
shelleyGenesis.ActiveSlotsCoeff.Rat,
|
|
283
|
-
).Num().Uint64()
|
|
284
|
-
stabilityWindowStartSlot := epochStartSlot - stabilityWindow
|
|
285
|
-
// Get last block before stability window
|
|
286
|
-
blockBeforeStabilityWindow, err := database.BlockBeforeSlotTxn(
|
|
287
|
-
txn,
|
|
288
|
-
stabilityWindowStartSlot,
|
|
289
|
-
)
|
|
290
|
-
if err != nil {
|
|
291
|
-
return nil, fmt.Errorf("lookup block before slot: %w", err)
|
|
292
|
-
}
|
|
293
|
-
// Get last block in previous epoch
|
|
294
|
-
blockLastPrevEpoch, err := database.BlockBeforeSlotTxn(
|
|
295
|
-
txn,
|
|
296
|
-
ls.currentEpoch.StartSlot,
|
|
297
|
-
)
|
|
298
|
-
if err != nil {
|
|
299
|
-
if errors.Is(err, database.ErrBlockNotFound) {
|
|
300
|
-
return blockBeforeStabilityWindow.Nonce, nil
|
|
301
|
-
}
|
|
302
|
-
return nil, fmt.Errorf("lookup block before slot: %w", err)
|
|
303
|
-
}
|
|
304
|
-
// Calculate nonce from inputs
|
|
305
|
-
ret, err := lcommon.CalculateEpochNonce(
|
|
306
|
-
blockBeforeStabilityWindow.Nonce,
|
|
307
|
-
blockLastPrevEpoch.PrevHash,
|
|
308
|
-
nil,
|
|
309
|
-
)
|
|
310
|
-
return ret.Bytes(), err
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
func (ls *LedgerState) processEpochRollover(
|
|
314
|
-
txn *database.Txn,
|
|
315
|
-
) error {
|
|
316
|
-
epochStartSlot := ls.currentEpoch.StartSlot + uint64(
|
|
317
|
-
ls.currentEpoch.LengthInSlots,
|
|
318
|
-
)
|
|
319
|
-
// Create initial epoch
|
|
320
|
-
if ls.currentEpoch.SlotLength == 0 {
|
|
321
|
-
// Create initial epoch record
|
|
322
|
-
epochSlotLength, epochLength, err := ls.currentEra.EpochLengthFunc(
|
|
323
|
-
ls.config.CardanoNodeConfig,
|
|
324
|
-
)
|
|
325
|
-
if err != nil {
|
|
326
|
-
return fmt.Errorf("calculate epoch length: %w", err)
|
|
327
|
-
}
|
|
328
|
-
tmpNonce, err := ls.calculateEpochNonce(txn, 0)
|
|
329
|
-
if err != nil {
|
|
330
|
-
return fmt.Errorf("calculate epoch nonce: %w", err)
|
|
331
|
-
}
|
|
332
|
-
err = ls.db.SetEpoch(
|
|
333
|
-
epochStartSlot,
|
|
334
|
-
0, // epoch
|
|
335
|
-
tmpNonce,
|
|
336
|
-
ls.currentEra.Id,
|
|
337
|
-
epochSlotLength,
|
|
338
|
-
epochLength,
|
|
339
|
-
txn,
|
|
340
|
-
)
|
|
341
|
-
if err != nil {
|
|
342
|
-
return fmt.Errorf("set epoch: %w", err)
|
|
343
|
-
}
|
|
344
|
-
// Reload epoch info
|
|
345
|
-
if err := ls.loadEpochs(txn); err != nil {
|
|
346
|
-
return fmt.Errorf("load epochs: %w", err)
|
|
347
|
-
}
|
|
348
|
-
ls.config.Logger.Debug(
|
|
349
|
-
"added initial epoch to DB",
|
|
350
|
-
"epoch", fmt.Sprintf("%+v", ls.currentEpoch),
|
|
351
|
-
"component", "ledger",
|
|
352
|
-
)
|
|
353
|
-
return nil
|
|
354
|
-
}
|
|
355
|
-
// Apply pending pparam updates
|
|
356
|
-
err := ls.db.ApplyPParamUpdates(
|
|
357
|
-
epochStartSlot,
|
|
358
|
-
ls.currentEpoch.EpochId,
|
|
359
|
-
ls.currentEra.Id,
|
|
360
|
-
&ls.currentPParams,
|
|
361
|
-
ls.currentEra.DecodePParamsUpdateFunc,
|
|
362
|
-
ls.currentEra.PParamsUpdateFunc,
|
|
363
|
-
txn,
|
|
364
|
-
)
|
|
365
|
-
if err != nil {
|
|
366
|
-
return fmt.Errorf("apply pparam updates: %w", err)
|
|
367
|
-
}
|
|
368
|
-
// Create next epoch record
|
|
369
|
-
epochSlotLength, epochLength, err := ls.currentEra.EpochLengthFunc(
|
|
370
|
-
ls.config.CardanoNodeConfig,
|
|
371
|
-
)
|
|
372
|
-
if err != nil {
|
|
373
|
-
return fmt.Errorf("calculate epoch length: %w", err)
|
|
374
|
-
}
|
|
375
|
-
tmpNonce, err := ls.calculateEpochNonce(txn, epochStartSlot)
|
|
376
|
-
if err != nil {
|
|
377
|
-
return fmt.Errorf("calculate epoch nonce: %w", err)
|
|
378
|
-
}
|
|
379
|
-
err = ls.db.SetEpoch(
|
|
380
|
-
epochStartSlot,
|
|
381
|
-
ls.currentEpoch.EpochId+1,
|
|
382
|
-
tmpNonce,
|
|
383
|
-
ls.currentEra.Id,
|
|
384
|
-
epochSlotLength,
|
|
385
|
-
epochLength,
|
|
386
|
-
txn,
|
|
387
|
-
)
|
|
388
|
-
if err != nil {
|
|
389
|
-
return fmt.Errorf("set epoch: %w", err)
|
|
390
|
-
}
|
|
391
|
-
// Reload epoch info
|
|
392
|
-
if err := ls.loadEpochs(txn); err != nil {
|
|
393
|
-
return fmt.Errorf("load epochs: %w", err)
|
|
394
|
-
}
|
|
395
|
-
ls.config.Logger.Debug(
|
|
396
|
-
"added next epoch to DB",
|
|
397
|
-
"epoch", fmt.Sprintf("%+v", ls.currentEpoch),
|
|
398
|
-
"component", "ledger",
|
|
399
|
-
)
|
|
400
|
-
return nil
|
|
401
|
-
}
|
|
402
|
-
|
|
403
|
-
func (ls *LedgerState) processBlockEvent(
|
|
404
|
-
txn *database.Txn,
|
|
405
|
-
e BlockfetchEvent,
|
|
406
|
-
) error {
|
|
407
|
-
// TODO: move this to ledger block processing
|
|
408
|
-
// Calculate block rolling nonce
|
|
409
|
-
var blockNonce []byte
|
|
410
|
-
if ls.currentEra.CalculateEtaVFunc != nil {
|
|
411
|
-
tmpEra := eras.Eras[e.Block.Era().Id]
|
|
412
|
-
tmpNonce, err := tmpEra.CalculateEtaVFunc(
|
|
413
|
-
ls.config.CardanoNodeConfig,
|
|
414
|
-
ls.currentTipBlockNonce,
|
|
415
|
-
e.Block,
|
|
416
|
-
)
|
|
417
|
-
if err != nil {
|
|
418
|
-
return fmt.Errorf("calculate etaV: %w", err)
|
|
419
|
-
}
|
|
420
|
-
blockNonce = tmpNonce
|
|
421
|
-
}
|
|
422
|
-
// Add block to chain
|
|
423
|
-
if err := ls.chain.AddBlock(e.Block, blockNonce, txn); err != nil {
|
|
424
|
-
// Ignore and log errors about block not fitting on chain or matching first header
|
|
425
|
-
if !errors.As(err, &chain.BlockNotFitChainTipError{}) &&
|
|
426
|
-
!errors.As(err, &chain.BlockNotMatchHeaderError{}) {
|
|
427
|
-
return fmt.Errorf("add chain block: %w", err)
|
|
428
|
-
}
|
|
429
|
-
ls.config.Logger.Warn(
|
|
430
|
-
fmt.Sprintf(
|
|
431
|
-
"ignoring blockfetch block: %s",
|
|
432
|
-
err,
|
|
433
|
-
),
|
|
434
|
-
)
|
|
435
|
-
}
|
|
436
|
-
return nil
|
|
437
|
-
}
|
|
438
|
-
|
|
439
|
-
func (ls *LedgerState) blockfetchRequestRangeStart(
|
|
440
|
-
connId ouroboros.ConnectionId,
|
|
441
|
-
start ocommon.Point,
|
|
442
|
-
end ocommon.Point,
|
|
443
|
-
) error {
|
|
444
|
-
err := ls.config.BlockfetchRequestRangeFunc(
|
|
445
|
-
connId,
|
|
446
|
-
start,
|
|
447
|
-
end,
|
|
448
|
-
)
|
|
449
|
-
if err != nil {
|
|
450
|
-
return fmt.Errorf("request block range: %w", err)
|
|
451
|
-
}
|
|
452
|
-
// Create our blockfetch done signal channel
|
|
453
|
-
ls.chainsyncBlockfetchDoneChan = make(chan struct{})
|
|
454
|
-
return nil
|
|
455
|
-
}
|
|
456
|
-
|
|
457
|
-
func (ls *LedgerState) blockfetchRequestRangeCleanup(resetFlags bool) {
|
|
458
|
-
// Reset buffer
|
|
459
|
-
ls.chainsyncBlockEvents = slices.Delete(
|
|
460
|
-
ls.chainsyncBlockEvents,
|
|
461
|
-
0,
|
|
462
|
-
len(ls.chainsyncBlockEvents),
|
|
463
|
-
)
|
|
464
|
-
// Close our blockfetch done signal channel
|
|
465
|
-
if ls.chainsyncBlockfetchDoneChan != nil {
|
|
466
|
-
close(ls.chainsyncBlockfetchDoneChan)
|
|
467
|
-
ls.chainsyncBlockfetchDoneChan = nil
|
|
468
|
-
}
|
|
469
|
-
// Reset flags
|
|
470
|
-
if resetFlags {
|
|
471
|
-
ls.chainsyncBlockfetchWaiting = false
|
|
472
|
-
}
|
|
473
|
-
}
|
|
474
|
-
|
|
475
|
-
func (ls *LedgerState) handleEventBlockfetchBatchDone(e BlockfetchEvent) error {
|
|
476
|
-
// Process pending block events
|
|
477
|
-
if err := ls.processBlockEvents(); err != nil {
|
|
478
|
-
ls.blockfetchRequestRangeCleanup(true)
|
|
479
|
-
return fmt.Errorf("process block events: %w", err)
|
|
480
|
-
}
|
|
481
|
-
// Check for pending block range request
|
|
482
|
-
if !ls.chainsyncBlockfetchWaiting ||
|
|
483
|
-
ls.chain.HeaderCount() == 0 {
|
|
484
|
-
// Allow collection of more block headers via chainsync
|
|
485
|
-
ls.blockfetchRequestRangeCleanup(true)
|
|
486
|
-
return nil
|
|
487
|
-
}
|
|
488
|
-
// Clean up from blockfetch batch
|
|
489
|
-
ls.blockfetchRequestRangeCleanup(false)
|
|
490
|
-
// Request next waiting bulk range
|
|
491
|
-
headerStart, headerEnd := ls.chain.HeaderRange(blockfetchBatchSize)
|
|
492
|
-
err := ls.blockfetchRequestRangeStart(
|
|
493
|
-
e.ConnectionId,
|
|
494
|
-
headerStart,
|
|
495
|
-
headerEnd,
|
|
496
|
-
)
|
|
497
|
-
if err != nil {
|
|
498
|
-
ls.blockfetchRequestRangeCleanup(true)
|
|
499
|
-
return err
|
|
500
|
-
}
|
|
501
|
-
ls.chainsyncBlockfetchBusyTime = time.Now()
|
|
502
|
-
ls.chainsyncBlockfetchWaiting = false
|
|
503
|
-
return nil
|
|
504
|
-
}
|