Skip to content

Commit 6040f74

Browse files
committed
feat: implement unified certificate persistence system
- Add SetCertificate method handling all Cardano certificate types - Switch interface from slot to ocommon.Point for consistency - Add comprehensive test suite with 19 test cases - Remove deprecated certificate setter methods - Include certificate mapping model and migration updates Signed-off-by: GitHub Copilot <[email protected]> Signed-off-by: Chris Gianelloni <[email protected]>
1 parent 9e93242 commit 6040f74

32 files changed

+2230
-1280
lines changed

database/account.go

Lines changed: 0 additions & 142 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,6 @@ package database
1616

1717
import (
1818
"github.com/blinklabs-io/dingo/database/models"
19-
"github.com/blinklabs-io/dingo/database/types"
20-
lcommon "github.com/blinklabs-io/gouroboros/ledger/common"
2119
)
2220

2321
// GetAccount returns an account by staking key
@@ -38,143 +36,3 @@ func (d *Database) GetAccount(
3836
}
3937
return account, nil
4038
}
41-
42-
// SetDeregistration saves a deregistration certificate
43-
func (d *Database) SetDeregistration(
44-
cert *lcommon.DeregistrationCertificate,
45-
slot uint64,
46-
txn *Txn,
47-
) error {
48-
return d.metadata.SetDeregistration(
49-
cert,
50-
slot,
51-
txn.Metadata(),
52-
)
53-
}
54-
55-
// SetRegistration saves a registration certificate
56-
func (d *Database) SetRegistration(
57-
cert *lcommon.RegistrationCertificate,
58-
slot uint64,
59-
deposit uint64,
60-
txn *Txn,
61-
) error {
62-
return d.metadata.SetRegistration(
63-
cert,
64-
slot,
65-
types.Uint64(deposit),
66-
txn.Metadata(),
67-
)
68-
}
69-
70-
// SetStakeDelegation saves a stake delegation certificate
71-
func (d *Database) SetStakeDelegation(
72-
cert *lcommon.StakeDelegationCertificate,
73-
slot uint64,
74-
txn *Txn,
75-
) error {
76-
return d.metadata.SetStakeDelegation(
77-
cert,
78-
slot,
79-
txn.Metadata(),
80-
)
81-
}
82-
83-
// SetStakeDeregistration saves a stake deregistration certificate
84-
func (d *Database) SetStakeDeregistration(
85-
cert *lcommon.StakeDeregistrationCertificate,
86-
slot uint64,
87-
txn *Txn,
88-
) error {
89-
return d.metadata.SetStakeDeregistration(
90-
cert,
91-
slot,
92-
txn.Metadata(),
93-
)
94-
}
95-
96-
// SetStakeRegistration saves a stake registration certificate
97-
func (d *Database) SetStakeRegistration(
98-
cert *lcommon.StakeRegistrationCertificate,
99-
slot uint64,
100-
deposit uint64,
101-
txn *Txn,
102-
) error {
103-
return d.metadata.SetStakeRegistration(
104-
cert,
105-
slot,
106-
types.Uint64(deposit),
107-
txn.Metadata(),
108-
)
109-
}
110-
111-
// SetStakeRegistrationDelegation saves a stake registration delegation certificate
112-
func (d *Database) SetStakeRegistrationDelegation(
113-
cert *lcommon.StakeRegistrationDelegationCertificate,
114-
slot uint64,
115-
deposit uint64,
116-
txn *Txn,
117-
) error {
118-
return d.metadata.SetStakeRegistrationDelegation(
119-
cert,
120-
slot,
121-
types.Uint64(deposit),
122-
txn.Metadata(),
123-
)
124-
}
125-
126-
// SetStakeVoteDelegation saves a stake vote delegation certificate
127-
func (d *Database) SetStakeVoteDelegation(
128-
cert *lcommon.StakeVoteDelegationCertificate,
129-
slot uint64,
130-
txn *Txn,
131-
) error {
132-
return d.metadata.SetStakeVoteDelegation(
133-
cert,
134-
slot,
135-
txn.Metadata(),
136-
)
137-
}
138-
139-
// SetStakeVoteRegistrationDelegation saves a stake vote registration delegation certificate
140-
func (d *Database) SetStakeVoteRegistrationDelegation(
141-
cert *lcommon.StakeVoteRegistrationDelegationCertificate,
142-
slot uint64,
143-
deposit uint64,
144-
txn *Txn,
145-
) error {
146-
return d.metadata.SetStakeVoteRegistrationDelegation(
147-
cert,
148-
slot,
149-
types.Uint64(deposit),
150-
txn.Metadata(),
151-
)
152-
}
153-
154-
// SetVoteDelegation saves a vote delegation certificate
155-
func (d *Database) SetVoteDelegation(
156-
cert *lcommon.VoteDelegationCertificate,
157-
slot uint64,
158-
txn *Txn,
159-
) error {
160-
return d.metadata.SetVoteDelegation(
161-
cert,
162-
slot,
163-
txn.Metadata(),
164-
)
165-
}
166-
167-
// SetVoteRegistrationDelegation saves a vote registration delegation certificate
168-
func (d *Database) SetVoteRegistrationDelegation(
169-
cert *lcommon.VoteRegistrationDelegationCertificate,
170-
slot uint64,
171-
deposit uint64,
172-
txn *Txn,
173-
) error {
174-
return d.metadata.SetVoteRegistrationDelegation(
175-
cert,
176-
slot,
177-
types.Uint64(deposit),
178-
txn.Metadata(),
179-
)
180-
}

database/certs.go renamed to database/certificate.go

Lines changed: 6 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -15,46 +15,25 @@
1515
package database
1616

1717
import (
18-
"github.com/blinklabs-io/dingo/database/types"
1918
lcommon "github.com/blinklabs-io/gouroboros/ledger/common"
2019
)
2120

22-
// GetPoolRegistrations returns a list of pool registration certificates
21+
// Certificate persistence is handled by SetTransaction.
22+
// The ledger layer calculates deposits and calls SetTransaction
23+
// to persist transactions and certificates together in a single operation.
24+
25+
// GetPoolRegistrations returns pool registration certificates for the given pool key hash
2326
func (d *Database) GetPoolRegistrations(
2427
poolKeyHash lcommon.PoolKeyHash,
2528
txn *Txn,
2629
) ([]lcommon.PoolRegistrationCertificate, error) {
2730
return d.metadata.GetPoolRegistrations(poolKeyHash, txn.Metadata())
2831
}
2932

30-
// GetStakeRegistrations returns a list of stake registration certificates
33+
// GetStakeRegistrations returns stake registration certificates for the given staking key
3134
func (d *Database) GetStakeRegistrations(
3235
stakingKey []byte,
3336
txn *Txn,
3437
) ([]lcommon.StakeRegistrationCertificate, error) {
3538
return d.metadata.GetStakeRegistrations(stakingKey, txn.Metadata())
3639
}
37-
38-
// SetPoolRegistration saves a pool registration certificate
39-
func (d *Database) SetPoolRegistration(
40-
cert *lcommon.PoolRegistrationCertificate,
41-
slot uint64,
42-
deposit uint64,
43-
txn *Txn,
44-
) error {
45-
return d.metadata.SetPoolRegistration(
46-
cert,
47-
slot,
48-
types.Uint64(deposit),
49-
txn.Metadata(),
50-
)
51-
}
52-
53-
// SetPoolRetirement saves a pool retirement certificate
54-
func (d *Database) SetPoolRetirement(
55-
cert *lcommon.PoolRetirementCertificate,
56-
slot uint64,
57-
txn *Txn,
58-
) error {
59-
return d.metadata.SetPoolRetirement(cert, slot, txn.Metadata())
60-
}

database/drep.go

Lines changed: 0 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -13,51 +13,3 @@
1313
// limitations under the License.
1414

1515
package database
16-
17-
import (
18-
"github.com/blinklabs-io/dingo/database/types"
19-
lcommon "github.com/blinklabs-io/gouroboros/ledger/common"
20-
)
21-
22-
// SetRegistrationDrep saves a registration drep certificate
23-
func (d *Database) SetRegistrationDrep(
24-
cert *lcommon.RegistrationDrepCertificate,
25-
slot uint64,
26-
deposit uint64,
27-
txn *Txn,
28-
) error {
29-
return d.metadata.SetRegistrationDrep(
30-
cert,
31-
slot,
32-
types.Uint64(deposit),
33-
txn.Metadata(),
34-
)
35-
}
36-
37-
// SetDeregistrationDrep saves a deregistration drep certificate
38-
func (d *Database) SetDeregistrationDrep(
39-
cert *lcommon.DeregistrationDrepCertificate,
40-
slot uint64,
41-
deposit uint64,
42-
txn *Txn,
43-
) error {
44-
return d.metadata.SetDeregistrationDrep(
45-
cert,
46-
slot,
47-
types.Uint64(deposit),
48-
txn.Metadata(),
49-
)
50-
}
51-
52-
// SetUpdateDrep saves an update drep certificate
53-
func (d *Database) SetUpdateDrep(
54-
cert *lcommon.UpdateDrepCertificate,
55-
slot uint64,
56-
txn *Txn,
57-
) error {
58-
return d.metadata.SetUpdateDrep(
59-
cert,
60-
slot,
61-
txn.Metadata(),
62-
)
63-
}

database/models/account.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ import (
2525
var ErrAccountNotFound = errors.New("account not found")
2626

2727
type Account struct {
28-
StakingKey []byte `gorm:"uniqueIndex"`
28+
StakingKey []byte `gorm:"index"`
2929
Pool []byte `gorm:"index"`
3030
Drep []byte `gorm:"index"`
3131
ID uint `gorm:"primarykey"`
@@ -58,9 +58,9 @@ func (a *Account) String() (string, error) {
5858
}
5959

6060
type Deregistration struct {
61-
StakingKey []byte `gorm:"index"`
61+
StakingKey []byte `gorm:"index;uniqueIndex:uniq_deregistration_cert"`
6262
ID uint `gorm:"primarykey"`
63-
CertificateID uint `gorm:"index"`
63+
CertificateID uint `gorm:"uniqueIndex:uniq_deregistration_cert"`
6464
AddedSlot uint64
6565
Amount types.Uint64
6666
}
@@ -105,8 +105,8 @@ func (StakeDeregistration) TableName() string {
105105
}
106106

107107
type StakeRegistration struct {
108-
StakingKey []byte `gorm:"index"`
109-
CertificateID uint `gorm:"index"`
108+
StakingKey []byte `gorm:"index;uniqueIndex:uniq_stake_registration_cert"`
109+
CertificateID uint `gorm:"uniqueIndex:uniq_stake_registration_cert"`
110110
ID uint `gorm:"primarykey"`
111111
AddedSlot uint64
112112
DepositAmount types.Uint64

database/models/account_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,11 @@ import (
2626
func TestAccount_String(t *testing.T) {
2727
tests := []struct {
2828
name string
29+
wantErrMsg string
30+
expectedHRP string
2931
stakingKey []byte
3032
wantErr bool
31-
wantErrMsg string
3233
validateAddr bool
33-
expectedHRP string
3434
}{
3535
{
3636
name: "valid staking key - 28 bytes",

database/models/auth_committee_hot.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,10 @@
1515
package models
1616

1717
type AuthCommitteeHot struct {
18-
ColdCredential []byte `gorm:"index"`
18+
ColdCredential []byte `gorm:"index;uniqueIndex:uniq_auth_committee_hot_cert"`
1919
HostCredential []byte `gorm:"index"`
2020
ID uint `gorm:"primarykey"`
21+
CertificateID uint `gorm:"uniqueIndex:uniq_auth_committee_hot_cert"`
2122
AddedSlot uint64
2223
}
2324

database/models/certificate.go

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
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 models
16+
17+
// Certificate maps transaction certificates to their specialized table records.
18+
// Provides unified indexing across all certificate types without requiring joins.
19+
//
20+
// All certificate types now have dedicated specialized models. The CertificateID field
21+
// references the ID of the specific certificate record based on CertType.
22+
type Certificate struct {
23+
BlockHash []byte `gorm:"index"`
24+
ID uint `gorm:"primaryKey"`
25+
TransactionID uint `gorm:"index;uniqueIndex:uniq_tx_cert;constraint:OnDelete:CASCADE"`
26+
CertificateID uint `gorm:"index"` // Polymorphic FK to certificate table based on CertType. Not DB-enforced.
27+
Slot uint64 `gorm:"index"`
28+
CertIndex uint `gorm:"column:cert_index;uniqueIndex:uniq_tx_cert"`
29+
CertType uint `gorm:"index"`
30+
}
31+
32+
// TableName returns the database table name for the Certificate model.
33+
func (Certificate) TableName() string {
34+
return "certificates"
35+
}
36+
37+
// Type returns the certificate type.
38+
func (c Certificate) Type() uint {
39+
return c.CertType
40+
}

0 commit comments

Comments
 (0)