@blinklabs/dingo 0.6.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.
- package/.dingo/blob/000001.sst +0 -0
- package/.dingo/blob/000001.vlog +0 -0
- package/.dingo/blob/DISCARD +0 -0
- package/.dingo/blob/KEYREGISTRY +2 -0
- package/.dingo/blob/MANIFEST +0 -0
- package/.dingo/metadata.sqlite +0 -0
- package/.github/workflows/golangci-lint.yml +1 -1
- package/.github/workflows/publish.yml +1 -7
- package/README.md +2 -1
- package/{dist/dingo_darwin_amd64_v1/dingo → dingo} +0 -0
- package/dingo.yaml.example +53 -0
- package/package.json +5 -5
- 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 -138
- 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 -27
- 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 -224
- 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/epoch.go +0 -120
- package/database/plugin/metadata/sqlite/models/account.go +0 -81
- package/database/plugin/metadata/sqlite/models/auth_committee_hot.go +0 -26
- package/database/plugin/metadata/sqlite/models/deregistration_drep.go +0 -26
- package/database/plugin/metadata/sqlite/models/drep.go +0 -27
- package/database/plugin/metadata/sqlite/models/epoch.go +0 -31
- package/database/plugin/metadata/sqlite/models/models.go +0 -45
- 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/registration_drep.go +0 -28
- package/database/plugin/metadata/sqlite/models/resign_committee_cold.go +0 -27
- package/database/plugin/metadata/sqlite/models/stake_registration_delegation.go +0 -27
- package/database/plugin/metadata/sqlite/models/stake_vote_delegation.go +0 -27
- package/database/plugin/metadata/sqlite/models/stake_vote_registration_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 -26
- 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 -168
- 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_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 -113
- package/ledger/chainsync.go +0 -578
- 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 -158
- 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 -260
- package/ledger/slot.go +0 -127
- package/ledger/slot_test.go +0 -147
- package/ledger/state.go +0 -726
- 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,113 +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
|
-
lcommon "github.com/blinklabs-io/gouroboros/ledger/common"
|
|
22
|
-
pcommon "github.com/blinklabs-io/gouroboros/protocol/common"
|
|
23
|
-
)
|
|
24
|
-
|
|
25
|
-
func (ls *LedgerState) processTransactionCertificates(
|
|
26
|
-
txn *database.Txn,
|
|
27
|
-
blockPoint pcommon.Point,
|
|
28
|
-
tx lcommon.Transaction,
|
|
29
|
-
) error {
|
|
30
|
-
var tmpCert lcommon.Certificate
|
|
31
|
-
for _, tmpCert = range tx.Certificates() {
|
|
32
|
-
certDeposit, err := ls.currentEra.CertDepositFunc(
|
|
33
|
-
tmpCert,
|
|
34
|
-
ls.currentPParams,
|
|
35
|
-
)
|
|
36
|
-
if err != nil {
|
|
37
|
-
return err
|
|
38
|
-
}
|
|
39
|
-
switch cert := tmpCert.(type) {
|
|
40
|
-
case *lcommon.DeregistrationCertificate:
|
|
41
|
-
err := ls.db.SetDeregistration(
|
|
42
|
-
cert,
|
|
43
|
-
blockPoint.Slot,
|
|
44
|
-
txn,
|
|
45
|
-
)
|
|
46
|
-
if err != nil {
|
|
47
|
-
return err
|
|
48
|
-
}
|
|
49
|
-
case *lcommon.PoolRegistrationCertificate:
|
|
50
|
-
err := ls.db.SetPoolRegistration(
|
|
51
|
-
cert,
|
|
52
|
-
blockPoint.Slot,
|
|
53
|
-
certDeposit,
|
|
54
|
-
txn,
|
|
55
|
-
)
|
|
56
|
-
if err != nil {
|
|
57
|
-
return err
|
|
58
|
-
}
|
|
59
|
-
case *lcommon.PoolRetirementCertificate:
|
|
60
|
-
err := ls.db.SetPoolRetirement(
|
|
61
|
-
cert,
|
|
62
|
-
blockPoint.Slot,
|
|
63
|
-
txn,
|
|
64
|
-
)
|
|
65
|
-
if err != nil {
|
|
66
|
-
return err
|
|
67
|
-
}
|
|
68
|
-
case *lcommon.RegistrationCertificate:
|
|
69
|
-
err := ls.db.SetRegistration(
|
|
70
|
-
cert,
|
|
71
|
-
blockPoint.Slot,
|
|
72
|
-
certDeposit,
|
|
73
|
-
txn,
|
|
74
|
-
)
|
|
75
|
-
if err != nil {
|
|
76
|
-
return err
|
|
77
|
-
}
|
|
78
|
-
case *lcommon.StakeDelegationCertificate:
|
|
79
|
-
err := ls.db.SetStakeDelegation(
|
|
80
|
-
cert,
|
|
81
|
-
blockPoint.Slot,
|
|
82
|
-
txn,
|
|
83
|
-
)
|
|
84
|
-
if err != nil {
|
|
85
|
-
return err
|
|
86
|
-
}
|
|
87
|
-
case *lcommon.StakeDeregistrationCertificate:
|
|
88
|
-
err := ls.db.SetStakeDeregistration(
|
|
89
|
-
cert,
|
|
90
|
-
blockPoint.Slot,
|
|
91
|
-
txn,
|
|
92
|
-
)
|
|
93
|
-
if err != nil {
|
|
94
|
-
return err
|
|
95
|
-
}
|
|
96
|
-
case *lcommon.StakeRegistrationCertificate:
|
|
97
|
-
err := ls.db.SetStakeRegistration(
|
|
98
|
-
cert,
|
|
99
|
-
blockPoint.Slot,
|
|
100
|
-
certDeposit,
|
|
101
|
-
txn,
|
|
102
|
-
)
|
|
103
|
-
if err != nil {
|
|
104
|
-
return err
|
|
105
|
-
}
|
|
106
|
-
default:
|
|
107
|
-
ls.config.Logger.Warn(
|
|
108
|
-
fmt.Sprintf("ignoring unsupported certificate type %T", cert),
|
|
109
|
-
)
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
return nil
|
|
113
|
-
}
|
package/ledger/chainsync.go
DELETED
|
@@ -1,578 +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
|
-
"github.com/blinklabs-io/gouroboros/ledger"
|
|
32
|
-
lcommon "github.com/blinklabs-io/gouroboros/ledger/common"
|
|
33
|
-
ocommon "github.com/blinklabs-io/gouroboros/protocol/common"
|
|
34
|
-
)
|
|
35
|
-
|
|
36
|
-
const (
|
|
37
|
-
// Max number of blocks to fetch in a single blockfetch call
|
|
38
|
-
// This prevents us exceeding the configured recv queue size in the block-fetch protocol
|
|
39
|
-
blockfetchBatchSize = 500
|
|
40
|
-
|
|
41
|
-
// TODO: calculate from protocol params
|
|
42
|
-
// Number of slots from upstream tip to stop doing blockfetch batches
|
|
43
|
-
blockfetchBatchSlotThreshold = 2500 * 20
|
|
44
|
-
|
|
45
|
-
// Timeout for updates on a blockfetch operation. This is based on a 2s BatchStart
|
|
46
|
-
// and a 2s Block timeout for blockfetch
|
|
47
|
-
blockfetchBusyTimeout = 5 * time.Second
|
|
48
|
-
)
|
|
49
|
-
|
|
50
|
-
func (ls *LedgerState) handleEventChainsync(evt event.Event) {
|
|
51
|
-
ls.chainsyncMutex.Lock()
|
|
52
|
-
defer ls.chainsyncMutex.Unlock()
|
|
53
|
-
e := evt.Data.(ChainsyncEvent)
|
|
54
|
-
if e.Rollback {
|
|
55
|
-
if err := ls.handleEventChainsyncRollback(e); err != nil {
|
|
56
|
-
// TODO: actually handle this error
|
|
57
|
-
ls.config.Logger.Error(
|
|
58
|
-
"failed to handle rollback",
|
|
59
|
-
"component", "ledger",
|
|
60
|
-
"error", err,
|
|
61
|
-
)
|
|
62
|
-
return
|
|
63
|
-
}
|
|
64
|
-
} else if e.BlockHeader != nil {
|
|
65
|
-
if err := ls.handleEventChainsyncBlockHeader(e); err != nil {
|
|
66
|
-
// TODO: actually handle this error
|
|
67
|
-
ls.config.Logger.Error(
|
|
68
|
-
fmt.Sprintf("ledger: failed to handle block header: %s", err),
|
|
69
|
-
)
|
|
70
|
-
return
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
func (ls *LedgerState) handleEventBlockfetch(evt event.Event) {
|
|
76
|
-
ls.chainsyncBlockfetchMutex.Lock()
|
|
77
|
-
defer ls.chainsyncBlockfetchMutex.Unlock()
|
|
78
|
-
e := evt.Data.(BlockfetchEvent)
|
|
79
|
-
if e.BatchDone {
|
|
80
|
-
if err := ls.handleEventBlockfetchBatchDone(e); err != nil {
|
|
81
|
-
// TODO: actually handle this error
|
|
82
|
-
ls.config.Logger.Error(
|
|
83
|
-
fmt.Sprintf(
|
|
84
|
-
"ledger: failed to handle blockfetch batch done: %s",
|
|
85
|
-
err,
|
|
86
|
-
),
|
|
87
|
-
)
|
|
88
|
-
}
|
|
89
|
-
} else if e.Block != nil {
|
|
90
|
-
if err := ls.handleEventBlockfetchBlock(e); err != nil {
|
|
91
|
-
// TODO: actually handle this error
|
|
92
|
-
ls.config.Logger.Error(
|
|
93
|
-
fmt.Sprintf("ledger: failed to handle block: %s", err),
|
|
94
|
-
)
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
func (ls *LedgerState) handleEventChainsyncRollback(e ChainsyncEvent) error {
|
|
100
|
-
if err := ls.chain.Rollback(e.Point); err != nil {
|
|
101
|
-
return err
|
|
102
|
-
}
|
|
103
|
-
return nil
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
func (ls *LedgerState) handleEventChainsyncBlockHeader(e ChainsyncEvent) error {
|
|
107
|
-
// Allow us to build up a few blockfetch batches worth of headers
|
|
108
|
-
allowedHeaderCount := blockfetchBatchSize * 4
|
|
109
|
-
headerCount := ls.chain.HeaderCount()
|
|
110
|
-
// Wait for current blockfetch batch to finish before we collect more block headers
|
|
111
|
-
if headerCount >= allowedHeaderCount {
|
|
112
|
-
// We assign the channel to a temp var to protect against trying to read from a nil channel
|
|
113
|
-
// without a race condition
|
|
114
|
-
tmpDoneChan := ls.chainsyncBlockfetchDoneChan
|
|
115
|
-
if tmpDoneChan != nil {
|
|
116
|
-
<-tmpDoneChan
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
// Add header to chain
|
|
120
|
-
if err := ls.chain.AddBlockHeader(e.BlockHeader); err != nil {
|
|
121
|
-
if !errors.As(err, &chain.BlockNotFitChainTipError{}) {
|
|
122
|
-
return err
|
|
123
|
-
}
|
|
124
|
-
ls.config.Logger.Warn(
|
|
125
|
-
fmt.Sprintf(
|
|
126
|
-
"ignoring chainsync block header: %s",
|
|
127
|
-
err,
|
|
128
|
-
),
|
|
129
|
-
)
|
|
130
|
-
return nil
|
|
131
|
-
}
|
|
132
|
-
// Wait for additional block headers before fetching block bodies if we're
|
|
133
|
-
// far enough out from upstream tip
|
|
134
|
-
if e.Point.Slot < e.Tip.Point.Slot &&
|
|
135
|
-
(e.Tip.Point.Slot-e.Point.Slot > blockfetchBatchSlotThreshold) &&
|
|
136
|
-
(headerCount+1) < allowedHeaderCount {
|
|
137
|
-
return nil
|
|
138
|
-
}
|
|
139
|
-
// We use the blockfetch lock to ensure we aren't starting a batch at the same
|
|
140
|
-
// time as blockfetch starts a new one to avoid deadlocks
|
|
141
|
-
ls.chainsyncBlockfetchMutex.Lock()
|
|
142
|
-
defer ls.chainsyncBlockfetchMutex.Unlock()
|
|
143
|
-
// Don't start fetch if there's already one in progress
|
|
144
|
-
if ls.chainsyncBlockfetchDoneChan != nil {
|
|
145
|
-
// Clear blockfetch busy flag on timeout
|
|
146
|
-
if time.Since(ls.chainsyncBlockfetchBusyTime) > blockfetchBusyTimeout {
|
|
147
|
-
ls.blockfetchRequestRangeCleanup(true)
|
|
148
|
-
ls.config.Logger.Warn(
|
|
149
|
-
fmt.Sprintf(
|
|
150
|
-
"blockfetch operation timed out after %s",
|
|
151
|
-
blockfetchBusyTimeout,
|
|
152
|
-
),
|
|
153
|
-
"component",
|
|
154
|
-
"ledger",
|
|
155
|
-
)
|
|
156
|
-
return nil
|
|
157
|
-
}
|
|
158
|
-
ls.chainsyncBlockfetchWaiting = true
|
|
159
|
-
return nil
|
|
160
|
-
}
|
|
161
|
-
// Request next bulk range
|
|
162
|
-
headerStart, headerEnd := ls.chain.HeaderRange(blockfetchBatchSize)
|
|
163
|
-
err := ls.blockfetchRequestRangeStart(
|
|
164
|
-
e.ConnectionId,
|
|
165
|
-
headerStart,
|
|
166
|
-
headerEnd,
|
|
167
|
-
)
|
|
168
|
-
if err != nil {
|
|
169
|
-
ls.blockfetchRequestRangeCleanup(true)
|
|
170
|
-
return err
|
|
171
|
-
}
|
|
172
|
-
ls.chainsyncBlockfetchBusyTime = time.Now()
|
|
173
|
-
return nil
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
//nolint:unparam
|
|
177
|
-
func (ls *LedgerState) handleEventBlockfetchBlock(e BlockfetchEvent) error {
|
|
178
|
-
ls.chainsyncBlockEvents = append(
|
|
179
|
-
ls.chainsyncBlockEvents,
|
|
180
|
-
e,
|
|
181
|
-
)
|
|
182
|
-
// Update busy time in order to detect fetch timeout
|
|
183
|
-
ls.chainsyncBlockfetchBusyTime = time.Now()
|
|
184
|
-
return nil
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
func (ls *LedgerState) processBlockEvents() error {
|
|
188
|
-
batchOffset := 0
|
|
189
|
-
for {
|
|
190
|
-
batchSize := min(
|
|
191
|
-
10, // Chosen to stay well under badger transaction size limit
|
|
192
|
-
len(ls.chainsyncBlockEvents)-batchOffset,
|
|
193
|
-
)
|
|
194
|
-
if batchSize <= 0 {
|
|
195
|
-
break
|
|
196
|
-
}
|
|
197
|
-
ls.Lock()
|
|
198
|
-
// Start a transaction
|
|
199
|
-
txn := ls.db.BlobTxn(true)
|
|
200
|
-
err := txn.Do(func(txn *database.Txn) error {
|
|
201
|
-
for _, evt := range ls.chainsyncBlockEvents[batchOffset : batchOffset+batchSize] {
|
|
202
|
-
if err := ls.processBlockEvent(txn, evt); err != nil {
|
|
203
|
-
return err
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
return nil
|
|
207
|
-
})
|
|
208
|
-
ls.Unlock()
|
|
209
|
-
if err != nil {
|
|
210
|
-
return err
|
|
211
|
-
}
|
|
212
|
-
batchOffset += batchSize
|
|
213
|
-
}
|
|
214
|
-
ls.chainsyncBlockEvents = nil
|
|
215
|
-
return nil
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
func (ls *LedgerState) createGenesisBlock() error {
|
|
219
|
-
if ls.currentEpoch.SlotLength > 0 {
|
|
220
|
-
return nil
|
|
221
|
-
}
|
|
222
|
-
txn := ls.db.Transaction(true)
|
|
223
|
-
err := txn.Do(func(txn *database.Txn) error {
|
|
224
|
-
// Record genesis UTxOs
|
|
225
|
-
byronGenesis := ls.config.CardanoNodeConfig.ByronGenesis()
|
|
226
|
-
genesisUtxos, err := byronGenesis.GenesisUtxos()
|
|
227
|
-
if err != nil {
|
|
228
|
-
return err
|
|
229
|
-
}
|
|
230
|
-
for _, utxo := range genesisUtxos {
|
|
231
|
-
outAddr := utxo.Output.Address()
|
|
232
|
-
outputCbor, err := cbor.Encode(utxo.Output)
|
|
233
|
-
if err != nil {
|
|
234
|
-
return err
|
|
235
|
-
}
|
|
236
|
-
err = ls.db.NewUtxo(
|
|
237
|
-
utxo.Id.Id().Bytes(),
|
|
238
|
-
utxo.Id.Index(),
|
|
239
|
-
0,
|
|
240
|
-
outAddr.PaymentKeyHash().Bytes(),
|
|
241
|
-
outAddr.StakeKeyHash().Bytes(),
|
|
242
|
-
outputCbor,
|
|
243
|
-
txn,
|
|
244
|
-
)
|
|
245
|
-
if err != nil {
|
|
246
|
-
return fmt.Errorf("add genesis UTxO: %w", err)
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
|
-
return nil
|
|
250
|
-
})
|
|
251
|
-
return err
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
func (ls *LedgerState) calculateEpochNonce(
|
|
255
|
-
txn *database.Txn,
|
|
256
|
-
epochStartSlot uint64,
|
|
257
|
-
) ([]byte, error) {
|
|
258
|
-
// No epoch nonce in Byron
|
|
259
|
-
if ls.currentEra.Id == 0 {
|
|
260
|
-
return nil, nil
|
|
261
|
-
}
|
|
262
|
-
// Use Shelley genesis hash for initial epoch nonce
|
|
263
|
-
if len(ls.currentEpoch.Nonce) == 0 {
|
|
264
|
-
genesisHashBytes, err := hex.DecodeString(
|
|
265
|
-
ls.config.CardanoNodeConfig.ShelleyGenesisHash,
|
|
266
|
-
)
|
|
267
|
-
return genesisHashBytes, err
|
|
268
|
-
}
|
|
269
|
-
// Calculate stability window
|
|
270
|
-
byronGenesis := ls.config.CardanoNodeConfig.ByronGenesis()
|
|
271
|
-
shelleyGenesis := ls.config.CardanoNodeConfig.ShelleyGenesis()
|
|
272
|
-
if byronGenesis == nil || shelleyGenesis == nil {
|
|
273
|
-
return nil, errors.New("could not get genesis config")
|
|
274
|
-
}
|
|
275
|
-
stabilityWindow := new(big.Rat).Quo(
|
|
276
|
-
big.NewRat(
|
|
277
|
-
int64(3*byronGenesis.ProtocolConsts.K),
|
|
278
|
-
1,
|
|
279
|
-
),
|
|
280
|
-
shelleyGenesis.ActiveSlotsCoeff.Rat,
|
|
281
|
-
).Num().Uint64()
|
|
282
|
-
stabilityWindowStartSlot := epochStartSlot - stabilityWindow
|
|
283
|
-
// Get last block before stability window
|
|
284
|
-
blockBeforeStabilityWindow, err := database.BlockBeforeSlotTxn(
|
|
285
|
-
txn,
|
|
286
|
-
stabilityWindowStartSlot,
|
|
287
|
-
)
|
|
288
|
-
if err != nil {
|
|
289
|
-
return nil, err
|
|
290
|
-
}
|
|
291
|
-
// Get last block in previous epoch
|
|
292
|
-
blockLastPrevEpoch, err := database.BlockBeforeSlotTxn(
|
|
293
|
-
txn,
|
|
294
|
-
ls.currentEpoch.StartSlot,
|
|
295
|
-
)
|
|
296
|
-
if err != nil {
|
|
297
|
-
if errors.Is(err, database.ErrBlockNotFound) {
|
|
298
|
-
return blockBeforeStabilityWindow.Nonce, nil
|
|
299
|
-
}
|
|
300
|
-
return nil, err
|
|
301
|
-
}
|
|
302
|
-
// Calculate nonce from inputs
|
|
303
|
-
ret, err := lcommon.CalculateEpochNonce(
|
|
304
|
-
blockBeforeStabilityWindow.Nonce,
|
|
305
|
-
blockLastPrevEpoch.PrevHash,
|
|
306
|
-
nil,
|
|
307
|
-
)
|
|
308
|
-
return ret.Bytes(), err
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
func (ls *LedgerState) processEpochRollover(
|
|
312
|
-
txn *database.Txn,
|
|
313
|
-
point ocommon.Point,
|
|
314
|
-
) error {
|
|
315
|
-
// Create initial epoch
|
|
316
|
-
if ls.currentEpoch.SlotLength == 0 {
|
|
317
|
-
// Create initial epoch record
|
|
318
|
-
epochSlotLength, epochLength, err := ls.currentEra.EpochLengthFunc(
|
|
319
|
-
ls.config.CardanoNodeConfig,
|
|
320
|
-
)
|
|
321
|
-
if err != nil {
|
|
322
|
-
return err
|
|
323
|
-
}
|
|
324
|
-
tmpNonce, err := ls.calculateEpochNonce(txn, 0)
|
|
325
|
-
if err != nil {
|
|
326
|
-
return err
|
|
327
|
-
}
|
|
328
|
-
err = ls.db.SetEpoch(
|
|
329
|
-
0, // start slot
|
|
330
|
-
0, // epoch
|
|
331
|
-
tmpNonce,
|
|
332
|
-
ls.currentEra.Id,
|
|
333
|
-
epochSlotLength,
|
|
334
|
-
epochLength,
|
|
335
|
-
txn,
|
|
336
|
-
)
|
|
337
|
-
if err != nil {
|
|
338
|
-
return err
|
|
339
|
-
}
|
|
340
|
-
// Reload epoch info
|
|
341
|
-
if err := ls.loadEpochs(txn); err != nil {
|
|
342
|
-
return err
|
|
343
|
-
}
|
|
344
|
-
ls.config.Logger.Debug(
|
|
345
|
-
"added initial epoch to DB",
|
|
346
|
-
"epoch", fmt.Sprintf("%+v", ls.currentEpoch),
|
|
347
|
-
"component", "ledger",
|
|
348
|
-
)
|
|
349
|
-
}
|
|
350
|
-
// Check for epoch rollover
|
|
351
|
-
if point.Slot > ls.currentEpoch.StartSlot+uint64(
|
|
352
|
-
ls.currentEpoch.LengthInSlots,
|
|
353
|
-
) {
|
|
354
|
-
// Apply pending pparam updates
|
|
355
|
-
err := ls.db.ApplyPParamUpdates(
|
|
356
|
-
point.Slot,
|
|
357
|
-
ls.currentEpoch.EpochId,
|
|
358
|
-
ls.currentEra.Id,
|
|
359
|
-
&ls.currentPParams,
|
|
360
|
-
ls.currentEra.DecodePParamsUpdateFunc,
|
|
361
|
-
ls.currentEra.PParamsUpdateFunc,
|
|
362
|
-
txn,
|
|
363
|
-
)
|
|
364
|
-
if err != nil {
|
|
365
|
-
return err
|
|
366
|
-
}
|
|
367
|
-
// Create next epoch record
|
|
368
|
-
epochSlotLength, epochLength, err := ls.currentEra.EpochLengthFunc(
|
|
369
|
-
ls.config.CardanoNodeConfig,
|
|
370
|
-
)
|
|
371
|
-
if err != nil {
|
|
372
|
-
return err
|
|
373
|
-
}
|
|
374
|
-
epochStartSlot := ls.currentEpoch.StartSlot + uint64(
|
|
375
|
-
ls.currentEpoch.LengthInSlots,
|
|
376
|
-
)
|
|
377
|
-
tmpNonce, err := ls.calculateEpochNonce(txn, epochStartSlot)
|
|
378
|
-
if err != nil {
|
|
379
|
-
return err
|
|
380
|
-
}
|
|
381
|
-
err = ls.db.SetEpoch(
|
|
382
|
-
epochStartSlot,
|
|
383
|
-
ls.currentEpoch.EpochId+1,
|
|
384
|
-
tmpNonce,
|
|
385
|
-
ls.currentEra.Id,
|
|
386
|
-
epochSlotLength,
|
|
387
|
-
epochLength,
|
|
388
|
-
txn,
|
|
389
|
-
)
|
|
390
|
-
if err != nil {
|
|
391
|
-
return err
|
|
392
|
-
}
|
|
393
|
-
// Reload epoch info
|
|
394
|
-
if err := ls.loadEpochs(txn); err != nil {
|
|
395
|
-
return err
|
|
396
|
-
}
|
|
397
|
-
ls.config.Logger.Debug(
|
|
398
|
-
"added next epoch to DB",
|
|
399
|
-
"epoch", fmt.Sprintf("%+v", ls.currentEpoch),
|
|
400
|
-
"component", "ledger",
|
|
401
|
-
)
|
|
402
|
-
}
|
|
403
|
-
return nil
|
|
404
|
-
}
|
|
405
|
-
|
|
406
|
-
func (ls *LedgerState) processBlockEvent(
|
|
407
|
-
txn *database.Txn,
|
|
408
|
-
e BlockfetchEvent,
|
|
409
|
-
) error {
|
|
410
|
-
// TODO: move this to ledger block processing
|
|
411
|
-
// Calculate block rolling nonce
|
|
412
|
-
var blockNonce []byte
|
|
413
|
-
if ls.currentEra.CalculateEtaVFunc != nil {
|
|
414
|
-
tmpEra := eras.Eras[e.Block.Era().Id]
|
|
415
|
-
tmpNonce, err := tmpEra.CalculateEtaVFunc(
|
|
416
|
-
ls.config.CardanoNodeConfig,
|
|
417
|
-
ls.currentTipBlockNonce,
|
|
418
|
-
e.Block,
|
|
419
|
-
)
|
|
420
|
-
if err != nil {
|
|
421
|
-
return err
|
|
422
|
-
}
|
|
423
|
-
blockNonce = tmpNonce
|
|
424
|
-
}
|
|
425
|
-
// Add block to chain
|
|
426
|
-
if err := ls.chain.AddBlock(e.Block, blockNonce, txn); err != nil {
|
|
427
|
-
// Ignore and log errors about block not fitting on chain or matching first header
|
|
428
|
-
if !errors.As(err, &chain.BlockNotFitChainTipError{}) &&
|
|
429
|
-
!errors.As(err, &chain.BlockNotMatchHeaderError{}) {
|
|
430
|
-
return err
|
|
431
|
-
}
|
|
432
|
-
ls.config.Logger.Warn(
|
|
433
|
-
fmt.Sprintf(
|
|
434
|
-
"ignoring blockfetch block: %s",
|
|
435
|
-
err,
|
|
436
|
-
),
|
|
437
|
-
)
|
|
438
|
-
}
|
|
439
|
-
return nil
|
|
440
|
-
}
|
|
441
|
-
|
|
442
|
-
func (ls *LedgerState) processTransaction(
|
|
443
|
-
txn *database.Txn,
|
|
444
|
-
tx ledger.Transaction,
|
|
445
|
-
point ocommon.Point,
|
|
446
|
-
) error {
|
|
447
|
-
// Validate transaction
|
|
448
|
-
if ls.currentEra.ValidateTxFunc != nil {
|
|
449
|
-
lv := &LedgerView{
|
|
450
|
-
txn: txn,
|
|
451
|
-
ls: ls,
|
|
452
|
-
}
|
|
453
|
-
err := ls.currentEra.ValidateTxFunc(
|
|
454
|
-
tx,
|
|
455
|
-
point.Slot,
|
|
456
|
-
lv,
|
|
457
|
-
ls.currentPParams,
|
|
458
|
-
)
|
|
459
|
-
if err != nil {
|
|
460
|
-
ls.config.Logger.Warn(
|
|
461
|
-
"TX " + tx.Hash().
|
|
462
|
-
String() +
|
|
463
|
-
" failed validation: " + err.Error(),
|
|
464
|
-
)
|
|
465
|
-
// return fmt.Errorf("TX validation failure: %w", err)
|
|
466
|
-
}
|
|
467
|
-
}
|
|
468
|
-
// Process consumed UTxOs
|
|
469
|
-
for _, consumed := range tx.Consumed() {
|
|
470
|
-
if err := ls.consumeUtxo(txn, consumed, point.Slot); err != nil {
|
|
471
|
-
return fmt.Errorf("remove consumed UTxO: %w", err)
|
|
472
|
-
}
|
|
473
|
-
}
|
|
474
|
-
// Process produced UTxOs
|
|
475
|
-
for _, produced := range tx.Produced() {
|
|
476
|
-
outAddr := produced.Output.Address()
|
|
477
|
-
err := ls.db.NewUtxo(
|
|
478
|
-
produced.Id.Id().Bytes(),
|
|
479
|
-
produced.Id.Index(),
|
|
480
|
-
point.Slot,
|
|
481
|
-
outAddr.PaymentKeyHash().Bytes(),
|
|
482
|
-
outAddr.StakeKeyHash().Bytes(),
|
|
483
|
-
produced.Output.Cbor(),
|
|
484
|
-
txn,
|
|
485
|
-
)
|
|
486
|
-
if err != nil {
|
|
487
|
-
return fmt.Errorf("add produced UTxO: %w", err)
|
|
488
|
-
}
|
|
489
|
-
}
|
|
490
|
-
// XXX: generate event for each TX/UTxO?
|
|
491
|
-
// Protocol parameter updates
|
|
492
|
-
if updateEpoch, paramUpdates := tx.ProtocolParameterUpdates(); updateEpoch > 0 {
|
|
493
|
-
for genesisHash, update := range paramUpdates {
|
|
494
|
-
err := ls.db.SetPParamUpdate(
|
|
495
|
-
genesisHash.Bytes(),
|
|
496
|
-
update.Cbor(),
|
|
497
|
-
point.Slot,
|
|
498
|
-
updateEpoch,
|
|
499
|
-
txn,
|
|
500
|
-
)
|
|
501
|
-
if err != nil {
|
|
502
|
-
return err
|
|
503
|
-
}
|
|
504
|
-
}
|
|
505
|
-
}
|
|
506
|
-
// Certificates
|
|
507
|
-
if err := ls.processTransactionCertificates(txn, point, tx); err != nil {
|
|
508
|
-
return err
|
|
509
|
-
}
|
|
510
|
-
return nil
|
|
511
|
-
}
|
|
512
|
-
|
|
513
|
-
func (ls *LedgerState) blockfetchRequestRangeStart(
|
|
514
|
-
connId ouroboros.ConnectionId,
|
|
515
|
-
start ocommon.Point,
|
|
516
|
-
end ocommon.Point,
|
|
517
|
-
) error {
|
|
518
|
-
err := ls.config.BlockfetchRequestRangeFunc(
|
|
519
|
-
connId,
|
|
520
|
-
start,
|
|
521
|
-
end,
|
|
522
|
-
)
|
|
523
|
-
if err != nil {
|
|
524
|
-
return err
|
|
525
|
-
}
|
|
526
|
-
// Create our blockfetch done signal channel
|
|
527
|
-
ls.chainsyncBlockfetchDoneChan = make(chan struct{})
|
|
528
|
-
return nil
|
|
529
|
-
}
|
|
530
|
-
|
|
531
|
-
func (ls *LedgerState) blockfetchRequestRangeCleanup(resetFlags bool) {
|
|
532
|
-
// Reset buffer
|
|
533
|
-
ls.chainsyncBlockEvents = slices.Delete(
|
|
534
|
-
ls.chainsyncBlockEvents,
|
|
535
|
-
0,
|
|
536
|
-
len(ls.chainsyncBlockEvents),
|
|
537
|
-
)
|
|
538
|
-
// Close our blockfetch done signal channel
|
|
539
|
-
if ls.chainsyncBlockfetchDoneChan != nil {
|
|
540
|
-
close(ls.chainsyncBlockfetchDoneChan)
|
|
541
|
-
ls.chainsyncBlockfetchDoneChan = nil
|
|
542
|
-
}
|
|
543
|
-
// Reset flags
|
|
544
|
-
if resetFlags {
|
|
545
|
-
ls.chainsyncBlockfetchWaiting = false
|
|
546
|
-
}
|
|
547
|
-
}
|
|
548
|
-
|
|
549
|
-
func (ls *LedgerState) handleEventBlockfetchBatchDone(e BlockfetchEvent) error {
|
|
550
|
-
// Process pending block events
|
|
551
|
-
if err := ls.processBlockEvents(); err != nil {
|
|
552
|
-
ls.blockfetchRequestRangeCleanup(true)
|
|
553
|
-
return err
|
|
554
|
-
}
|
|
555
|
-
// Check for pending block range request
|
|
556
|
-
if !ls.chainsyncBlockfetchWaiting ||
|
|
557
|
-
ls.chain.HeaderCount() == 0 {
|
|
558
|
-
// Allow collection of more block headers via chainsync
|
|
559
|
-
ls.blockfetchRequestRangeCleanup(true)
|
|
560
|
-
return nil
|
|
561
|
-
}
|
|
562
|
-
// Clean up from blockfetch batch
|
|
563
|
-
ls.blockfetchRequestRangeCleanup(false)
|
|
564
|
-
// Request next waiting bulk range
|
|
565
|
-
headerStart, headerEnd := ls.chain.HeaderRange(blockfetchBatchSize)
|
|
566
|
-
err := ls.blockfetchRequestRangeStart(
|
|
567
|
-
e.ConnectionId,
|
|
568
|
-
headerStart,
|
|
569
|
-
headerEnd,
|
|
570
|
-
)
|
|
571
|
-
if err != nil {
|
|
572
|
-
ls.blockfetchRequestRangeCleanup(true)
|
|
573
|
-
return err
|
|
574
|
-
}
|
|
575
|
-
ls.chainsyncBlockfetchBusyTime = time.Now()
|
|
576
|
-
ls.chainsyncBlockfetchWaiting = false
|
|
577
|
-
return nil
|
|
578
|
-
}
|