@blinklabs/dingo 0.6.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/.dockerignore +5 -0
- package/.github/CODEOWNERS +5 -0
- 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 +19 -0
- package/.github/dingo-20241210.png +0 -0
- package/.github/dingo.md +56 -0
- package/.github/workflows/ci-docker.yml +36 -0
- package/.github/workflows/conventional-commits.yml +17 -0
- package/.github/workflows/go-test.yml +29 -0
- package/.github/workflows/golangci-lint.yml +23 -0
- package/.github/workflows/publish.yml +207 -0
- package/.golangci.yml +71 -0
- package/Dockerfile +25 -0
- package/LICENSE +201 -0
- package/Makefile +53 -0
- package/README.md +150 -0
- package/blockfetch.go +144 -0
- package/chain/chain.go +504 -0
- package/chain/chain_test.go +468 -0
- package/chain/errors.go +80 -0
- package/chain/event.go +33 -0
- package/chain/iter.go +64 -0
- package/chainsync/chainsync.go +97 -0
- package/chainsync.go +223 -0
- package/cmd/dingo/load.go +52 -0
- package/cmd/dingo/main.go +118 -0
- package/cmd/dingo/serve.go +49 -0
- package/config/cardano/node.go +192 -0
- package/config/cardano/node_test.go +85 -0
- package/config/cardano/preview/README.md +4 -0
- package/config/cardano/preview/alonzo-genesis.json +196 -0
- package/config/cardano/preview/byron-genesis.json +117 -0
- package/config/cardano/preview/config.json +114 -0
- package/config/cardano/preview/conway-genesis.json +297 -0
- package/config/cardano/preview/shelley-genesis.json +68 -0
- package/config.go +245 -0
- package/connmanager/connection_manager.go +105 -0
- package/connmanager/connection_manager_test.go +185 -0
- package/connmanager/event.go +37 -0
- package/connmanager/listener.go +140 -0
- package/connmanager/outbound.go +93 -0
- package/connmanager/socket.go +55 -0
- package/connmanager/unix.go +78 -0
- package/custom-p2p-topology.json +24 -0
- package/custom-p2p-topology.json.backup +24 -0
- package/custom-p2p-topology.json.mainnet +37 -0
- package/database/account.go +138 -0
- package/database/block.go +362 -0
- package/database/certs.go +53 -0
- package/database/commit_timestamp.go +77 -0
- package/database/database.go +118 -0
- package/database/database_test.go +62 -0
- package/database/drep.go +27 -0
- package/database/epoch.go +121 -0
- package/database/immutable/chunk.go +182 -0
- package/database/immutable/immutable.go +350 -0
- package/database/immutable/immutable_test.go +59 -0
- package/database/immutable/primary.go +106 -0
- package/database/immutable/secondary.go +103 -0
- 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 +4 -0
- package/database/plugin/blob/badger/commit_timestamp.go +50 -0
- package/database/plugin/blob/badger/database.go +152 -0
- package/database/plugin/blob/badger/logger.go +63 -0
- package/database/plugin/blob/badger/metrics.go +98 -0
- package/database/plugin/blob/blob.go +19 -0
- package/database/plugin/blob/store.go +40 -0
- package/database/plugin/log.go +27 -0
- package/database/plugin/metadata/metadata.go +19 -0
- package/database/plugin/metadata/sqlite/account.go +224 -0
- package/database/plugin/metadata/sqlite/certs.go +58 -0
- package/database/plugin/metadata/sqlite/commit_timestamp.go +68 -0
- package/database/plugin/metadata/sqlite/database.go +218 -0
- package/database/plugin/metadata/sqlite/epoch.go +120 -0
- package/database/plugin/metadata/sqlite/models/account.go +81 -0
- package/database/plugin/metadata/sqlite/models/auth_committee_hot.go +26 -0
- package/database/plugin/metadata/sqlite/models/deregistration_drep.go +26 -0
- package/database/plugin/metadata/sqlite/models/drep.go +27 -0
- package/database/plugin/metadata/sqlite/models/epoch.go +31 -0
- package/database/plugin/metadata/sqlite/models/models.go +45 -0
- package/database/plugin/metadata/sqlite/models/pool.go +97 -0
- package/database/plugin/metadata/sqlite/models/pparam_update.go +27 -0
- package/database/plugin/metadata/sqlite/models/pparams.go +27 -0
- package/database/plugin/metadata/sqlite/models/registration_drep.go +28 -0
- package/database/plugin/metadata/sqlite/models/resign_committee_cold.go +27 -0
- package/database/plugin/metadata/sqlite/models/stake_registration_delegation.go +27 -0
- package/database/plugin/metadata/sqlite/models/stake_vote_delegation.go +27 -0
- package/database/plugin/metadata/sqlite/models/stake_vote_registration_delegation.go +27 -0
- package/database/plugin/metadata/sqlite/models/tip.go +26 -0
- package/database/plugin/metadata/sqlite/models/update_drep.go +27 -0
- package/database/plugin/metadata/sqlite/models/utxo.go +30 -0
- package/database/plugin/metadata/sqlite/models/vote_delegation.go +26 -0
- package/database/plugin/metadata/sqlite/models/vote_registration_delegation.go +26 -0
- package/database/plugin/metadata/sqlite/pool.go +240 -0
- package/database/plugin/metadata/sqlite/pparams.go +110 -0
- package/database/plugin/metadata/sqlite/tip.go +83 -0
- package/database/plugin/metadata/sqlite/utxo.go +292 -0
- package/database/plugin/metadata/store.go +168 -0
- package/database/plugin/option.go +190 -0
- package/database/plugin/plugin.go +20 -0
- package/database/plugin/register.go +118 -0
- package/database/pparams.go +145 -0
- package/database/tip.go +45 -0
- package/database/txn.go +147 -0
- package/database/types/types.go +74 -0
- package/database/types/types_test.go +83 -0
- package/database/utxo.go +263 -0
- package/dist/artifacts.json +1 -0
- package/dist/checksums.txt +22 -0
- package/dist/config.yaml +253 -0
- package/dist/dingo-0.5.0-SNAPSHOT-d9431e4.tar.gz +0 -0
- package/dist/dingo-0.5.0-SNAPSHOT-d9431e4.tar.gz.sbom.json +1 -0
- 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 +1 -0
- 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 +1 -0
- 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 +1 -0
- 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 +1 -0
- 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 +1 -0
- 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 +1 -0
- 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 +1 -0
- 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 +1 -0
- 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 +1 -0
- 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 +1 -0
- 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 +51 -0
- package/dist/metadata.json +1 -0
- package/event/event.go +141 -0
- package/event/event_test.go +115 -0
- package/event/metrics.go +44 -0
- package/go.mod +98 -0
- package/go.sum +358 -0
- package/internal/config/config.go +145 -0
- package/internal/config/config_test.go +118 -0
- package/internal/node/load.go +149 -0
- package/internal/node/node.go +176 -0
- package/internal/version/version.go +33 -0
- package/ledger/certs.go +113 -0
- package/ledger/chainsync.go +578 -0
- package/ledger/eras/allegra.go +154 -0
- package/ledger/eras/alonzo.go +156 -0
- package/ledger/eras/babbage.go +154 -0
- package/ledger/eras/byron.go +42 -0
- package/ledger/eras/conway.go +158 -0
- package/ledger/eras/eras.go +44 -0
- package/ledger/eras/mary.go +154 -0
- package/ledger/eras/shelley.go +164 -0
- package/ledger/error.go +19 -0
- package/ledger/event.go +50 -0
- package/ledger/metrics.go +53 -0
- package/ledger/queries.go +260 -0
- package/ledger/slot.go +127 -0
- package/ledger/slot_test.go +147 -0
- package/ledger/state.go +726 -0
- package/ledger/view.go +73 -0
- package/localstatequery.go +50 -0
- package/localtxmonitor.go +44 -0
- package/localtxsubmission.go +52 -0
- package/mempool/consumer.go +98 -0
- package/mempool/mempool.go +322 -0
- package/node.go +320 -0
- package/package.json +33 -0
- package/peergov/event.go +27 -0
- package/peergov/peer.go +67 -0
- package/peergov/peergov.go +290 -0
- package/peersharing.go +70 -0
- package/preview-local-topology.json +23 -0
- package/topology/topology.go +69 -0
- package/topology/topology_test.go +179 -0
- package/tracing.go +65 -0
- package/txsubmission.go +233 -0
- package/utxorpc/query.go +311 -0
- package/utxorpc/submit.go +395 -0
- package/utxorpc/sync.go +276 -0
- package/utxorpc/utxorpc.go +166 -0
- package/utxorpc/watch.go +310 -0
|
@@ -0,0 +1,154 @@
|
|
|
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 eras
|
|
16
|
+
|
|
17
|
+
import (
|
|
18
|
+
"encoding/hex"
|
|
19
|
+
"errors"
|
|
20
|
+
"fmt"
|
|
21
|
+
|
|
22
|
+
"github.com/blinklabs-io/dingo/config/cardano"
|
|
23
|
+
"github.com/blinklabs-io/gouroboros/cbor"
|
|
24
|
+
"github.com/blinklabs-io/gouroboros/ledger"
|
|
25
|
+
"github.com/blinklabs-io/gouroboros/ledger/allegra"
|
|
26
|
+
lcommon "github.com/blinklabs-io/gouroboros/ledger/common"
|
|
27
|
+
"github.com/blinklabs-io/gouroboros/ledger/mary"
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
var MaryEraDesc = EraDesc{
|
|
31
|
+
Id: mary.EraIdMary,
|
|
32
|
+
Name: mary.EraNameMary,
|
|
33
|
+
DecodePParamsFunc: DecodePParamsMary,
|
|
34
|
+
DecodePParamsUpdateFunc: DecodePParamsUpdateMary,
|
|
35
|
+
PParamsUpdateFunc: PParamsUpdateMary,
|
|
36
|
+
HardForkFunc: HardForkMary,
|
|
37
|
+
EpochLengthFunc: EpochLengthShelley,
|
|
38
|
+
CalculateEtaVFunc: CalculateEtaVMary,
|
|
39
|
+
CertDepositFunc: CertDepositMary,
|
|
40
|
+
ValidateTxFunc: ValidateTxMary,
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
func DecodePParamsMary(data []byte) (lcommon.ProtocolParameters, error) {
|
|
44
|
+
var ret mary.MaryProtocolParameters
|
|
45
|
+
if _, err := cbor.Decode(data, &ret); err != nil {
|
|
46
|
+
return nil, err
|
|
47
|
+
}
|
|
48
|
+
return &ret, nil
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
func DecodePParamsUpdateMary(data []byte) (any, error) {
|
|
52
|
+
var ret mary.MaryProtocolParameterUpdate
|
|
53
|
+
if _, err := cbor.Decode(data, &ret); err != nil {
|
|
54
|
+
return nil, err
|
|
55
|
+
}
|
|
56
|
+
return ret, nil
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
func PParamsUpdateMary(
|
|
60
|
+
currentPParams lcommon.ProtocolParameters,
|
|
61
|
+
pparamsUpdate any,
|
|
62
|
+
) (lcommon.ProtocolParameters, error) {
|
|
63
|
+
maryPParams, ok := currentPParams.(*mary.MaryProtocolParameters)
|
|
64
|
+
if !ok {
|
|
65
|
+
return nil, fmt.Errorf(
|
|
66
|
+
"current PParams (%T) is not expected type",
|
|
67
|
+
currentPParams,
|
|
68
|
+
)
|
|
69
|
+
}
|
|
70
|
+
maryPParamsUpdate, ok := pparamsUpdate.(mary.MaryProtocolParameterUpdate)
|
|
71
|
+
if !ok {
|
|
72
|
+
return nil, fmt.Errorf(
|
|
73
|
+
"PParams update (%T) is not expected type",
|
|
74
|
+
pparamsUpdate,
|
|
75
|
+
)
|
|
76
|
+
}
|
|
77
|
+
maryPParams.Update(&maryPParamsUpdate)
|
|
78
|
+
return maryPParams, nil
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
func HardForkMary(
|
|
82
|
+
nodeConfig *cardano.CardanoNodeConfig,
|
|
83
|
+
prevPParams lcommon.ProtocolParameters,
|
|
84
|
+
) (lcommon.ProtocolParameters, error) {
|
|
85
|
+
allegraPParams, ok := prevPParams.(*allegra.AllegraProtocolParameters)
|
|
86
|
+
if !ok {
|
|
87
|
+
return nil, fmt.Errorf(
|
|
88
|
+
"previous PParams (%T) are not expected type",
|
|
89
|
+
prevPParams,
|
|
90
|
+
)
|
|
91
|
+
}
|
|
92
|
+
ret := mary.UpgradePParams(*allegraPParams)
|
|
93
|
+
return &ret, nil
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
func CalculateEtaVMary(
|
|
97
|
+
nodeConfig *cardano.CardanoNodeConfig,
|
|
98
|
+
prevBlockNonce []byte,
|
|
99
|
+
block ledger.Block,
|
|
100
|
+
) ([]byte, error) {
|
|
101
|
+
if len(prevBlockNonce) == 0 {
|
|
102
|
+
tmpNonce, err := hex.DecodeString(nodeConfig.ShelleyGenesisHash)
|
|
103
|
+
if err != nil {
|
|
104
|
+
return nil, err
|
|
105
|
+
}
|
|
106
|
+
prevBlockNonce = tmpNonce
|
|
107
|
+
}
|
|
108
|
+
h, ok := block.Header().(*mary.MaryBlockHeader)
|
|
109
|
+
if !ok {
|
|
110
|
+
return nil, errors.New("unexpected block type")
|
|
111
|
+
}
|
|
112
|
+
tmpNonce, err := lcommon.CalculateRollingNonce(
|
|
113
|
+
prevBlockNonce,
|
|
114
|
+
h.Body.NonceVrf.Output,
|
|
115
|
+
)
|
|
116
|
+
if err != nil {
|
|
117
|
+
return nil, err
|
|
118
|
+
}
|
|
119
|
+
return tmpNonce.Bytes(), nil
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
func CertDepositMary(
|
|
123
|
+
cert lcommon.Certificate,
|
|
124
|
+
pp lcommon.ProtocolParameters,
|
|
125
|
+
) (uint64, error) {
|
|
126
|
+
tmpPparams, ok := pp.(*mary.MaryProtocolParameters)
|
|
127
|
+
if !ok {
|
|
128
|
+
return 0, errors.New("pparams are not expected type")
|
|
129
|
+
}
|
|
130
|
+
switch cert.(type) {
|
|
131
|
+
case *lcommon.PoolRegistrationCertificate:
|
|
132
|
+
return uint64(tmpPparams.PoolDeposit), nil
|
|
133
|
+
case *lcommon.StakeRegistrationCertificate:
|
|
134
|
+
return uint64(tmpPparams.KeyDeposit), nil
|
|
135
|
+
default:
|
|
136
|
+
return 0, nil
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
func ValidateTxMary(
|
|
141
|
+
tx lcommon.Transaction,
|
|
142
|
+
slot uint64,
|
|
143
|
+
ls lcommon.LedgerState,
|
|
144
|
+
pp lcommon.ProtocolParameters,
|
|
145
|
+
) error {
|
|
146
|
+
errs := []error{}
|
|
147
|
+
for _, validationFunc := range mary.UtxoValidationRules {
|
|
148
|
+
errs = append(
|
|
149
|
+
errs,
|
|
150
|
+
validationFunc(tx, slot, ls, pp),
|
|
151
|
+
)
|
|
152
|
+
}
|
|
153
|
+
return errors.Join(errs...)
|
|
154
|
+
}
|
|
@@ -0,0 +1,164 @@
|
|
|
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 eras
|
|
16
|
+
|
|
17
|
+
import (
|
|
18
|
+
"encoding/hex"
|
|
19
|
+
"errors"
|
|
20
|
+
"fmt"
|
|
21
|
+
|
|
22
|
+
"github.com/blinklabs-io/dingo/config/cardano"
|
|
23
|
+
"github.com/blinklabs-io/gouroboros/cbor"
|
|
24
|
+
"github.com/blinklabs-io/gouroboros/ledger"
|
|
25
|
+
lcommon "github.com/blinklabs-io/gouroboros/ledger/common"
|
|
26
|
+
"github.com/blinklabs-io/gouroboros/ledger/shelley"
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
var ShelleyEraDesc = EraDesc{
|
|
30
|
+
Id: shelley.EraIdShelley,
|
|
31
|
+
Name: shelley.EraNameShelley,
|
|
32
|
+
DecodePParamsFunc: DecodePParamsShelley,
|
|
33
|
+
DecodePParamsUpdateFunc: DecodePParamsUpdateShelley,
|
|
34
|
+
PParamsUpdateFunc: PParamsUpdateShelley,
|
|
35
|
+
HardForkFunc: HardForkShelley,
|
|
36
|
+
EpochLengthFunc: EpochLengthShelley,
|
|
37
|
+
CalculateEtaVFunc: CalculateEtaVShelley,
|
|
38
|
+
CertDepositFunc: CertDepositShelley,
|
|
39
|
+
ValidateTxFunc: ValidateTxShelley,
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
func DecodePParamsShelley(data []byte) (lcommon.ProtocolParameters, error) {
|
|
43
|
+
var ret shelley.ShelleyProtocolParameters
|
|
44
|
+
if _, err := cbor.Decode(data, &ret); err != nil {
|
|
45
|
+
return nil, err
|
|
46
|
+
}
|
|
47
|
+
return &ret, nil
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
func DecodePParamsUpdateShelley(data []byte) (any, error) {
|
|
51
|
+
var ret shelley.ShelleyProtocolParameterUpdate
|
|
52
|
+
if _, err := cbor.Decode(data, &ret); err != nil {
|
|
53
|
+
return nil, err
|
|
54
|
+
}
|
|
55
|
+
return ret, nil
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
func PParamsUpdateShelley(
|
|
59
|
+
currentPParams lcommon.ProtocolParameters,
|
|
60
|
+
pparamsUpdate any,
|
|
61
|
+
) (lcommon.ProtocolParameters, error) {
|
|
62
|
+
shelleyPParams, ok := currentPParams.(*shelley.ShelleyProtocolParameters)
|
|
63
|
+
if !ok {
|
|
64
|
+
return nil, fmt.Errorf(
|
|
65
|
+
"current PParams (%T) is not expected type",
|
|
66
|
+
currentPParams,
|
|
67
|
+
)
|
|
68
|
+
}
|
|
69
|
+
shelleyPParamsUpdate, ok := pparamsUpdate.(shelley.ShelleyProtocolParameterUpdate)
|
|
70
|
+
if !ok {
|
|
71
|
+
return nil, fmt.Errorf(
|
|
72
|
+
"PParams update (%T) is not expected type",
|
|
73
|
+
pparamsUpdate,
|
|
74
|
+
)
|
|
75
|
+
}
|
|
76
|
+
shelleyPParams.Update(&shelleyPParamsUpdate)
|
|
77
|
+
return shelleyPParams, nil
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
func HardForkShelley(
|
|
81
|
+
nodeConfig *cardano.CardanoNodeConfig,
|
|
82
|
+
prevPParams lcommon.ProtocolParameters,
|
|
83
|
+
) (lcommon.ProtocolParameters, error) {
|
|
84
|
+
// There's no Byron protocol parameters to upgrade from, so this is mostly
|
|
85
|
+
// a dummy call for consistency
|
|
86
|
+
ret := shelley.UpgradePParams(nil)
|
|
87
|
+
shelleyGenesis := nodeConfig.ShelleyGenesis()
|
|
88
|
+
ret.UpdateFromGenesis(shelleyGenesis)
|
|
89
|
+
return &ret, nil
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
func EpochLengthShelley(
|
|
93
|
+
nodeConfig *cardano.CardanoNodeConfig,
|
|
94
|
+
) (uint, uint, error) {
|
|
95
|
+
shelleyGenesis := nodeConfig.ShelleyGenesis()
|
|
96
|
+
if shelleyGenesis == nil {
|
|
97
|
+
return 0, 0, errors.New("unable to get shelley genesis")
|
|
98
|
+
}
|
|
99
|
+
// These are known to be within uint range
|
|
100
|
+
// #nosec G115
|
|
101
|
+
return uint(shelleyGenesis.SlotLength * 1000),
|
|
102
|
+
uint(shelleyGenesis.EpochLength),
|
|
103
|
+
nil
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
func CalculateEtaVShelley(
|
|
107
|
+
nodeConfig *cardano.CardanoNodeConfig,
|
|
108
|
+
prevBlockNonce []byte,
|
|
109
|
+
block ledger.Block,
|
|
110
|
+
) ([]byte, error) {
|
|
111
|
+
if len(prevBlockNonce) == 0 {
|
|
112
|
+
tmpNonce, err := hex.DecodeString(nodeConfig.ShelleyGenesisHash)
|
|
113
|
+
if err != nil {
|
|
114
|
+
return nil, err
|
|
115
|
+
}
|
|
116
|
+
prevBlockNonce = tmpNonce
|
|
117
|
+
}
|
|
118
|
+
h, ok := block.Header().(*shelley.ShelleyBlockHeader)
|
|
119
|
+
if !ok {
|
|
120
|
+
return nil, errors.New("unexpected block type")
|
|
121
|
+
}
|
|
122
|
+
tmpNonce, err := lcommon.CalculateRollingNonce(
|
|
123
|
+
prevBlockNonce,
|
|
124
|
+
h.Body.NonceVrf.Output,
|
|
125
|
+
)
|
|
126
|
+
if err != nil {
|
|
127
|
+
return nil, err
|
|
128
|
+
}
|
|
129
|
+
return tmpNonce.Bytes(), nil
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
func CertDepositShelley(
|
|
133
|
+
cert lcommon.Certificate,
|
|
134
|
+
pp lcommon.ProtocolParameters,
|
|
135
|
+
) (uint64, error) {
|
|
136
|
+
tmpPparams, ok := pp.(*shelley.ShelleyProtocolParameters)
|
|
137
|
+
if !ok {
|
|
138
|
+
return 0, errors.New("pparams are not expected type")
|
|
139
|
+
}
|
|
140
|
+
switch cert.(type) {
|
|
141
|
+
case *lcommon.PoolRegistrationCertificate:
|
|
142
|
+
return uint64(tmpPparams.PoolDeposit), nil
|
|
143
|
+
case *lcommon.StakeRegistrationCertificate:
|
|
144
|
+
return uint64(tmpPparams.KeyDeposit), nil
|
|
145
|
+
default:
|
|
146
|
+
return 0, nil
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
func ValidateTxShelley(
|
|
151
|
+
tx lcommon.Transaction,
|
|
152
|
+
slot uint64,
|
|
153
|
+
ls lcommon.LedgerState,
|
|
154
|
+
pp lcommon.ProtocolParameters,
|
|
155
|
+
) error {
|
|
156
|
+
errs := []error{}
|
|
157
|
+
for _, validationFunc := range shelley.UtxoValidationRules {
|
|
158
|
+
errs = append(
|
|
159
|
+
errs,
|
|
160
|
+
validationFunc(tx, slot, ls, pp),
|
|
161
|
+
)
|
|
162
|
+
}
|
|
163
|
+
return errors.Join(errs...)
|
|
164
|
+
}
|
package/ledger/error.go
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
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 ledger
|
|
16
|
+
|
|
17
|
+
import "errors"
|
|
18
|
+
|
|
19
|
+
var ErrBlockNotFound = errors.New("block not found")
|
package/ledger/event.go
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
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 ledger
|
|
16
|
+
|
|
17
|
+
import (
|
|
18
|
+
"github.com/blinklabs-io/dingo/event"
|
|
19
|
+
ouroboros "github.com/blinklabs-io/gouroboros"
|
|
20
|
+
"github.com/blinklabs-io/gouroboros/ledger"
|
|
21
|
+
ochainsync "github.com/blinklabs-io/gouroboros/protocol/chainsync"
|
|
22
|
+
ocommon "github.com/blinklabs-io/gouroboros/protocol/common"
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
const (
|
|
26
|
+
BlockfetchEventType event.EventType = "blockfetch.event"
|
|
27
|
+
ChainsyncEventType event.EventType = "chainsync.event"
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
// BlockfetchEvent represents either a Block or BatchDone blockfetch event. We use
|
|
31
|
+
// a single event type for both to make synchronization easier.
|
|
32
|
+
type BlockfetchEvent struct {
|
|
33
|
+
ConnectionId ouroboros.ConnectionId // Connection ID associated with event
|
|
34
|
+
Point ocommon.Point // Chain point for block
|
|
35
|
+
Block ledger.Block
|
|
36
|
+
Type uint // Block type ID
|
|
37
|
+
BatchDone bool // Set to true for a BatchDone event
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// ChainsyncEvent represents either a RollForward or RollBackward chainsync event.
|
|
41
|
+
// We use a single event type for both to make synchronization easier.
|
|
42
|
+
type ChainsyncEvent struct {
|
|
43
|
+
ConnectionId ouroboros.ConnectionId // Connection ID associated with event
|
|
44
|
+
Point ocommon.Point // Chain point for roll forward/backward
|
|
45
|
+
Tip ochainsync.Tip // Upstream chain tip
|
|
46
|
+
BlockNumber uint64
|
|
47
|
+
BlockHeader ledger.BlockHeader
|
|
48
|
+
Type uint // Block or header type ID
|
|
49
|
+
Rollback bool
|
|
50
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
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 ledger
|
|
16
|
+
|
|
17
|
+
import (
|
|
18
|
+
"github.com/prometheus/client_golang/prometheus"
|
|
19
|
+
"github.com/prometheus/client_golang/prometheus/promauto"
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
type stateMetrics struct {
|
|
23
|
+
blockNum prometheus.Gauge
|
|
24
|
+
density prometheus.Gauge
|
|
25
|
+
epochNum prometheus.Gauge
|
|
26
|
+
slotInEpoch prometheus.Gauge
|
|
27
|
+
slotNum prometheus.Gauge
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
func (m *stateMetrics) init(promRegistry prometheus.Registerer) {
|
|
31
|
+
promautoFactory := promauto.With(promRegistry)
|
|
32
|
+
m.blockNum = promautoFactory.NewGauge(prometheus.GaugeOpts{
|
|
33
|
+
Name: "cardano_node_metrics_blockNum_int",
|
|
34
|
+
Help: "current block number",
|
|
35
|
+
})
|
|
36
|
+
// TODO: figure out how to calculate this (#390)
|
|
37
|
+
m.density = promautoFactory.NewGauge(prometheus.GaugeOpts{
|
|
38
|
+
Name: "cardano_node_metrics_density_real",
|
|
39
|
+
Help: "chain density",
|
|
40
|
+
})
|
|
41
|
+
m.epochNum = promautoFactory.NewGauge(prometheus.GaugeOpts{
|
|
42
|
+
Name: "cardano_node_metrics_epoch_int",
|
|
43
|
+
Help: "current epoch number",
|
|
44
|
+
})
|
|
45
|
+
m.slotInEpoch = promautoFactory.NewGauge(prometheus.GaugeOpts{
|
|
46
|
+
Name: "cardano_node_metrics_slotInEpoch_int",
|
|
47
|
+
Help: "current relative slot number in epoch",
|
|
48
|
+
})
|
|
49
|
+
m.slotNum = promautoFactory.NewGauge(prometheus.GaugeOpts{
|
|
50
|
+
Name: "cardano_node_metrics_slotNum_int",
|
|
51
|
+
Help: "current slot number",
|
|
52
|
+
})
|
|
53
|
+
}
|
|
@@ -0,0 +1,260 @@
|
|
|
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
|
+
"errors"
|
|
19
|
+
"fmt"
|
|
20
|
+
"math/big"
|
|
21
|
+
|
|
22
|
+
"github.com/blinklabs-io/dingo/database"
|
|
23
|
+
"github.com/blinklabs-io/dingo/ledger/eras"
|
|
24
|
+
"github.com/blinklabs-io/gouroboros/cbor"
|
|
25
|
+
"github.com/blinklabs-io/gouroboros/ledger"
|
|
26
|
+
olocalstatequery "github.com/blinklabs-io/gouroboros/protocol/localstatequery"
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
func (ls *LedgerState) Query(query any) (any, error) {
|
|
30
|
+
switch q := query.(type) {
|
|
31
|
+
case *olocalstatequery.BlockQuery:
|
|
32
|
+
return ls.queryBlock(q)
|
|
33
|
+
case *olocalstatequery.SystemStartQuery:
|
|
34
|
+
return ls.querySystemStart()
|
|
35
|
+
case *olocalstatequery.ChainBlockNoQuery:
|
|
36
|
+
return ls.queryChainBlockNo()
|
|
37
|
+
case *olocalstatequery.ChainPointQuery:
|
|
38
|
+
return ls.queryChainPoint()
|
|
39
|
+
default:
|
|
40
|
+
return nil, fmt.Errorf("unsupported query type: %T", q)
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
func (ls *LedgerState) queryBlock(
|
|
45
|
+
query *olocalstatequery.BlockQuery,
|
|
46
|
+
) (any, error) {
|
|
47
|
+
switch q := query.Query.(type) {
|
|
48
|
+
case *olocalstatequery.HardForkQuery:
|
|
49
|
+
return ls.queryHardFork(q)
|
|
50
|
+
case *olocalstatequery.ShelleyQuery:
|
|
51
|
+
return ls.queryShelley(q)
|
|
52
|
+
default:
|
|
53
|
+
return nil, fmt.Errorf("unsupported query type: %T", q)
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
func (ls *LedgerState) querySystemStart() (any, error) {
|
|
58
|
+
shelleyGenesis := ls.config.CardanoNodeConfig.ShelleyGenesis()
|
|
59
|
+
if shelleyGenesis == nil {
|
|
60
|
+
return nil, errors.New(
|
|
61
|
+
"unable to get shelley era genesis for system start",
|
|
62
|
+
)
|
|
63
|
+
}
|
|
64
|
+
// Nanosecond is always within uint64 range
|
|
65
|
+
// #nosec G115
|
|
66
|
+
ret := olocalstatequery.SystemStartResult{
|
|
67
|
+
Year: shelleyGenesis.SystemStart.Year(),
|
|
68
|
+
Day: shelleyGenesis.SystemStart.YearDay(),
|
|
69
|
+
Picoseconds: uint64(shelleyGenesis.SystemStart.Nanosecond() * 1000),
|
|
70
|
+
}
|
|
71
|
+
return ret, nil
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
func (ls *LedgerState) queryChainBlockNo() (any, error) {
|
|
75
|
+
ret := []any{
|
|
76
|
+
1, // TODO: figure out what this value is (#393)
|
|
77
|
+
ls.currentTip.BlockNumber,
|
|
78
|
+
}
|
|
79
|
+
return ret, nil
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
func (ls *LedgerState) queryChainPoint() (any, error) {
|
|
83
|
+
return ls.currentTip.Point, nil
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
func (ls *LedgerState) queryHardFork(
|
|
87
|
+
query *olocalstatequery.HardForkQuery,
|
|
88
|
+
) (any, error) {
|
|
89
|
+
switch q := query.Query.(type) {
|
|
90
|
+
case *olocalstatequery.HardForkCurrentEraQuery:
|
|
91
|
+
return ls.currentEra.Id, nil
|
|
92
|
+
case *olocalstatequery.HardForkEraHistoryQuery:
|
|
93
|
+
return ls.queryHardForkEraHistory()
|
|
94
|
+
default:
|
|
95
|
+
return nil, fmt.Errorf("unsupported query type: %T", q)
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
func (ls *LedgerState) queryHardForkEraHistory() (any, error) {
|
|
100
|
+
retData := []any{}
|
|
101
|
+
timespan := big.NewInt(0)
|
|
102
|
+
var epochs []database.Epoch
|
|
103
|
+
var era eras.EraDesc
|
|
104
|
+
var err error
|
|
105
|
+
var tmpStart, tmpEnd []any
|
|
106
|
+
var tmpEpoch database.Epoch
|
|
107
|
+
var tmpEra, tmpParams []any
|
|
108
|
+
var epochSlotLength, epochLength uint
|
|
109
|
+
var idx int
|
|
110
|
+
for _, era = range eras.Eras {
|
|
111
|
+
epochSlotLength, epochLength, err = era.EpochLengthFunc(
|
|
112
|
+
ls.config.CardanoNodeConfig,
|
|
113
|
+
)
|
|
114
|
+
if err != nil {
|
|
115
|
+
return nil, err
|
|
116
|
+
}
|
|
117
|
+
epochs, err = ls.db.GetEpochsByEra(era.Id, nil)
|
|
118
|
+
if err != nil {
|
|
119
|
+
return nil, err
|
|
120
|
+
}
|
|
121
|
+
tmpStart = []any{0, 0, 0}
|
|
122
|
+
tmpEnd = tmpStart
|
|
123
|
+
tmpParams = []any{
|
|
124
|
+
epochLength,
|
|
125
|
+
epochSlotLength,
|
|
126
|
+
[]any{
|
|
127
|
+
0,
|
|
128
|
+
0,
|
|
129
|
+
[]any{0},
|
|
130
|
+
},
|
|
131
|
+
0,
|
|
132
|
+
}
|
|
133
|
+
for idx, tmpEpoch = range epochs {
|
|
134
|
+
// Update era start
|
|
135
|
+
if idx == 0 {
|
|
136
|
+
tmpStart = []any{
|
|
137
|
+
new(big.Int).Set(timespan),
|
|
138
|
+
tmpEpoch.StartSlot,
|
|
139
|
+
tmpEpoch.EpochId,
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
// Add epoch length in picoseconds to timespan
|
|
143
|
+
timespan.Add(
|
|
144
|
+
timespan,
|
|
145
|
+
new(big.Int).SetUint64(
|
|
146
|
+
uint64(
|
|
147
|
+
tmpEpoch.SlotLength*tmpEpoch.LengthInSlots*1_000_000_000,
|
|
148
|
+
),
|
|
149
|
+
),
|
|
150
|
+
)
|
|
151
|
+
// Update era end
|
|
152
|
+
if idx == len(epochs)-1 {
|
|
153
|
+
tmpEnd = []any{
|
|
154
|
+
new(big.Int).Set(timespan),
|
|
155
|
+
tmpEpoch.StartSlot + uint64(tmpEpoch.LengthInSlots),
|
|
156
|
+
tmpEpoch.EpochId + 1,
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
tmpEra = []any{
|
|
161
|
+
tmpStart,
|
|
162
|
+
tmpEnd,
|
|
163
|
+
tmpParams,
|
|
164
|
+
}
|
|
165
|
+
retData = append(retData, tmpEra)
|
|
166
|
+
}
|
|
167
|
+
return cbor.IndefLengthList(retData), nil
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
func (ls *LedgerState) queryShelley(
|
|
171
|
+
query *olocalstatequery.ShelleyQuery,
|
|
172
|
+
) (any, error) {
|
|
173
|
+
switch q := query.Query.(type) {
|
|
174
|
+
case *olocalstatequery.ShelleyEpochNoQuery:
|
|
175
|
+
return []any{ls.currentEpoch.EpochId}, nil
|
|
176
|
+
case *olocalstatequery.ShelleyCurrentProtocolParamsQuery:
|
|
177
|
+
return []any{ls.currentPParams}, nil
|
|
178
|
+
case *olocalstatequery.ShelleyGenesisConfigQuery:
|
|
179
|
+
return ls.queryShelleyGenesisConfig()
|
|
180
|
+
case *olocalstatequery.ShelleyUtxoByAddressQuery:
|
|
181
|
+
return ls.queryShelleyUtxoByAddress(q.Addrs)
|
|
182
|
+
case *olocalstatequery.ShelleyUtxoByTxinQuery:
|
|
183
|
+
return ls.queryShelleyUtxoByTxIn(q.TxIns)
|
|
184
|
+
// TODO (#394)
|
|
185
|
+
/*
|
|
186
|
+
case *olocalstatequery.ShelleyLedgerTipQuery:
|
|
187
|
+
case *olocalstatequery.ShelleyNonMyopicMemberRewardsQuery:
|
|
188
|
+
case *olocalstatequery.ShelleyProposedProtocolParamsUpdatesQuery:
|
|
189
|
+
case *olocalstatequery.ShelleyStakeDistributionQuery:
|
|
190
|
+
case *olocalstatequery.ShelleyUtxoWholeQuery:
|
|
191
|
+
case *olocalstatequery.ShelleyDebugEpochStateQuery:
|
|
192
|
+
case *olocalstatequery.ShelleyCborQuery:
|
|
193
|
+
case *olocalstatequery.ShelleyFilteredDelegationAndRewardAccountsQuery:
|
|
194
|
+
case *olocalstatequery.ShelleyDebugNewEpochStateQuery:
|
|
195
|
+
case *olocalstatequery.ShelleyDebugChainDepStateQuery:
|
|
196
|
+
case *olocalstatequery.ShelleyRewardProvenanceQuery:
|
|
197
|
+
case *olocalstatequery.ShelleyStakePoolsQuery:
|
|
198
|
+
case *olocalstatequery.ShelleyStakePoolParamsQuery:
|
|
199
|
+
case *olocalstatequery.ShelleyRewardInfoPoolsQuery:
|
|
200
|
+
case *olocalstatequery.ShelleyPoolStateQuery:
|
|
201
|
+
case *olocalstatequery.ShelleyStakeSnapshotsQuery:
|
|
202
|
+
case *olocalstatequery.ShelleyPoolDistrQuery:
|
|
203
|
+
*/
|
|
204
|
+
default:
|
|
205
|
+
return nil, fmt.Errorf("unsupported query type: %T", q)
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
func (ls *LedgerState) queryShelleyGenesisConfig() (any, error) {
|
|
210
|
+
shelleyGenesis := ls.config.CardanoNodeConfig.ShelleyGenesis()
|
|
211
|
+
return []any{shelleyGenesis}, nil
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
func (ls *LedgerState) queryShelleyUtxoByAddress(
|
|
215
|
+
addrs []ledger.Address,
|
|
216
|
+
) (any, error) {
|
|
217
|
+
ret := make(map[olocalstatequery.UtxoId]ledger.TransactionOutput)
|
|
218
|
+
// TODO: support multiple addresses (#391)
|
|
219
|
+
utxos, err := ls.db.UtxosByAddress(addrs[0], nil)
|
|
220
|
+
if err != nil {
|
|
221
|
+
return nil, err
|
|
222
|
+
}
|
|
223
|
+
for _, utxo := range utxos {
|
|
224
|
+
txOut, err := utxo.Decode()
|
|
225
|
+
if err != nil {
|
|
226
|
+
return nil, err
|
|
227
|
+
}
|
|
228
|
+
utxoId := olocalstatequery.UtxoId{
|
|
229
|
+
Hash: ledger.NewBlake2b256(utxo.TxId),
|
|
230
|
+
Idx: int(utxo.OutputIdx),
|
|
231
|
+
}
|
|
232
|
+
ret[utxoId] = txOut
|
|
233
|
+
}
|
|
234
|
+
return []any{ret}, nil
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
func (ls *LedgerState) queryShelleyUtxoByTxIn(
|
|
238
|
+
txIns []ledger.ShelleyTransactionInput,
|
|
239
|
+
) (any, error) {
|
|
240
|
+
ret := make(map[olocalstatequery.UtxoId]ledger.TransactionOutput)
|
|
241
|
+
// TODO: support multiple TxIns (#392)
|
|
242
|
+
utxo, err := ls.db.UtxoByRef(
|
|
243
|
+
txIns[0].Id().Bytes(),
|
|
244
|
+
txIns[0].Index(),
|
|
245
|
+
nil,
|
|
246
|
+
)
|
|
247
|
+
if err != nil {
|
|
248
|
+
return nil, err
|
|
249
|
+
}
|
|
250
|
+
txOut, err := utxo.Decode()
|
|
251
|
+
if err != nil {
|
|
252
|
+
return nil, err
|
|
253
|
+
}
|
|
254
|
+
utxoId := olocalstatequery.UtxoId{
|
|
255
|
+
Hash: ledger.NewBlake2b256(utxo.TxId),
|
|
256
|
+
Idx: int(utxo.OutputIdx),
|
|
257
|
+
}
|
|
258
|
+
ret[utxoId] = txOut
|
|
259
|
+
return []any{ret}, nil
|
|
260
|
+
}
|