Skip to content

Commit 6d6530d

Browse files
author
Jenita
committed
feat: track witness set for transaction
Signed-off-by: Jenita <jkawan@blinklabs.io>
1 parent eb6ab54 commit 6d6530d

File tree

6 files changed

+128
-43
lines changed

6 files changed

+128
-43
lines changed

database/models/models.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,16 +26,20 @@ var MigrateModels = []any{
2626
&DeregistrationDrep{},
2727
&Drep{},
2828
&Epoch{},
29+
&KeyWitness{},
2930
&Pool{},
3031
&PoolRegistration{},
3132
&PoolRegistrationOwner{},
3233
&PoolRegistrationRelay{},
3334
&PoolRetirement{},
3435
&PParams{},
3536
&PParamUpdate{},
37+
&PlutusData{},
3638
&Registration{},
3739
&RegistrationDrep{},
40+
&Redeemer{},
3841
&ResignCommitteeCold{},
42+
&Script{},
3943
&StakeDelegation{},
4044
&StakeDeregistration{},
4145
&StakeRegistration{},
@@ -48,8 +52,4 @@ var MigrateModels = []any{
4852
&Utxo{},
4953
&VoteDelegation{},
5054
&VoteRegistrationDelegation{},
51-
&Witness{},
52-
&Script{},
53-
&Redeemer{},
54-
&PlutusData{},
5555
}

database/models/redeemer.go

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -14,23 +14,11 @@
1414

1515
package models
1616

17-
// RedeemerTag represents the tag for a redeemer (spend, mint, cert, reward, voting, proposing)
18-
type RedeemerTag uint8
19-
20-
const (
21-
RedeemerTagSpend RedeemerTag = 0
22-
RedeemerTagMint RedeemerTag = 1
23-
RedeemerTagCert RedeemerTag = 2
24-
RedeemerTagReward RedeemerTag = 3
25-
RedeemerTagVoting RedeemerTag = 4
26-
RedeemerTagProposing RedeemerTag = 5
27-
)
28-
2917
// Redeemer represents a redeemer in the witness set
3018
type Redeemer struct {
3119
ID uint `gorm:"primaryKey"`
3220
TransactionID uint `gorm:"index"`
33-
Tag uint8 `gorm:"index"` // RedeemerTag
21+
Tag uint8 `gorm:"index"` // Redeemer tag
3422
Index uint32 `gorm:"index"`
3523
Data []byte `gorm:"type:bytea"` // Plutus data
3624
ExUnitsMemory uint64

database/models/script.go

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,21 +14,16 @@
1414

1515
package models
1616

17-
// ScriptType represents the type of script
18-
type ScriptType uint8
19-
20-
const (
21-
ScriptTypeNative ScriptType = 0
22-
ScriptTypePlutusV1 ScriptType = 1
23-
ScriptTypePlutusV2 ScriptType = 2
24-
ScriptTypePlutusV3 ScriptType = 3
25-
)
26-
2717
// Script represents a script entry in the witness set
18+
// Type corresponds to ScriptRefType constants from gouroboros/ledger/common:
19+
// 0=NativeScript (ScriptRefTypeNativeScript)
20+
// 1=PlutusV1 (ScriptRefTypePlutusV1)
21+
// 2=PlutusV2 (ScriptRefTypePlutusV2)
22+
// 3=PlutusV3 (ScriptRefTypePlutusV3)
2823
type Script struct {
2924
ID uint `gorm:"primaryKey"`
3025
TransactionID uint `gorm:"index"`
31-
Type uint8 `gorm:"index"` // ScriptType (0=Native, 1=PlutusV1, 2=PlutusV2, 3=PlutusV3)
26+
Type uint8 `gorm:"index"` // Script type
3227
ScriptData []byte `gorm:"type:bytea"`
3328
Transaction *Transaction
3429
}

database/models/transaction.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,10 @@ type Transaction struct {
2323
ReferenceInputs []Utxo `gorm:"foreignKey:ReferencedByTxId;references:Hash"`
2424
Collateral []Utxo `gorm:"foreignKey:CollateralByTxId;references:Hash"`
2525
CollateralReturn *Utxo `gorm:"foreignKey:TransactionID;references:ID"`
26-
Witnesses []Witness `gorm:"foreignKey:TransactionID;references:ID"`
26+
KeyWitnesses []KeyWitness `gorm:"foreignKey:TransactionID;references:ID"`
2727
Scripts []Script `gorm:"foreignKey:TransactionID;references:ID"`
2828
Redeemers []Redeemer `gorm:"foreignKey:TransactionID;references:ID"`
29-
PlutusDataList []PlutusData `gorm:"foreignKey:TransactionID;references:ID"`
29+
PlutusData []PlutusData `gorm:"foreignKey:TransactionID;references:ID"`
3030
ID uint `gorm:"primaryKey"`
3131
Type int
3232
BlockIndex uint32

database/models/witness.go

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -14,19 +14,12 @@
1414

1515
package models
1616

17-
// WitnessType represents the type of witness
18-
type WitnessType uint8
19-
20-
const (
21-
WitnessTypeVkey WitnessType = 0
22-
WitnessTypeBootstrap WitnessType = 1
23-
)
24-
25-
// Witness represents a witness entry (Vkey or Bootstrap)
26-
type Witness struct {
17+
// KeyWitness represents a key witness entry (Vkey or Bootstrap)
18+
// Type: 0 = VkeyWitness, 1 = BootstrapWitness
19+
type KeyWitness struct {
2720
ID uint `gorm:"primaryKey"`
2821
TransactionID uint `gorm:"index"`
29-
Type uint8 `gorm:"index"` // WitnessType (0=Vkey, 1=Bootstrap)
22+
Type uint8 `gorm:"index"` // 0=Vkey, 1=Bootstrap
3023
Vkey []byte `gorm:"type:bytea"`
3124
Signature []byte `gorm:"type:bytea"`
3225
PublicKey []byte `gorm:"type:bytea"` // For Bootstrap
@@ -35,6 +28,6 @@ type Witness struct {
3528
Transaction *Transaction
3629
}
3730

38-
func (Witness) TableName() string {
39-
return "witness"
31+
func (KeyWitness) TableName() string {
32+
return "key_witness"
4033
}

database/plugin/metadata/sqlite/transaction.go

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,115 @@ func (d *MetadataStoreSqlite) SetTransaction(
277277
return result.Error
278278
}
279279
}
280+
// Extract and save witness set data
281+
if tx.Witnesses() != nil {
282+
ws := tx.Witnesses()
283+
284+
// Add Vkey Witnesses
285+
for _, vkey := range ws.Vkey() {
286+
keyWitness := models.KeyWitness{
287+
TransactionID: tmpTx.ID,
288+
Type: 0, // VkeyWitness
289+
Vkey: vkey.Vkey,
290+
Signature: vkey.Signature,
291+
}
292+
if result := txn.Create(&keyWitness); result.Error != nil {
293+
return fmt.Errorf("create vkey witness: %w", result.Error)
294+
}
295+
}
296+
297+
// Add Bootstrap Witnesses
298+
for _, bootstrap := range ws.Bootstrap() {
299+
keyWitness := models.KeyWitness{
300+
TransactionID: tmpTx.ID,
301+
Type: 1, // BootstrapWitness
302+
PublicKey: bootstrap.PublicKey,
303+
Signature: bootstrap.Signature,
304+
ChainCode: bootstrap.ChainCode,
305+
Attributes: bootstrap.Attributes,
306+
}
307+
if result := txn.Create(&keyWitness); result.Error != nil {
308+
return fmt.Errorf("create bootstrap witness: %w", result.Error)
309+
}
310+
}
311+
312+
// Add Native Scripts
313+
for _, script := range ws.NativeScripts() {
314+
scriptRecord := models.Script{
315+
TransactionID: tmpTx.ID,
316+
Type: uint8(lcommon.ScriptRefTypeNativeScript),
317+
ScriptData: script.Cbor(),
318+
}
319+
if result := txn.Create(&scriptRecord); result.Error != nil {
320+
return fmt.Errorf("create native script: %w", result.Error)
321+
}
322+
}
323+
324+
// Add PlutusV1 Scripts
325+
for _, script := range ws.PlutusV1Scripts() {
326+
scriptRecord := models.Script{
327+
TransactionID: tmpTx.ID,
328+
Type: uint8(lcommon.ScriptRefTypePlutusV1),
329+
ScriptData: script,
330+
}
331+
if result := txn.Create(&scriptRecord); result.Error != nil {
332+
return fmt.Errorf("create plutus v1 script: %w", result.Error)
333+
}
334+
}
335+
336+
// Add PlutusV2 Scripts
337+
for _, script := range ws.PlutusV2Scripts() {
338+
scriptRecord := models.Script{
339+
TransactionID: tmpTx.ID,
340+
Type: uint8(lcommon.ScriptRefTypePlutusV2),
341+
ScriptData: script,
342+
}
343+
if result := txn.Create(&scriptRecord); result.Error != nil {
344+
return fmt.Errorf("create plutus v2 script: %w", result.Error)
345+
}
346+
}
347+
348+
// Add PlutusV3 Scripts
349+
for _, script := range ws.PlutusV3Scripts() {
350+
scriptRecord := models.Script{
351+
TransactionID: tmpTx.ID,
352+
Type: uint8(lcommon.ScriptRefTypePlutusV3),
353+
ScriptData: script,
354+
}
355+
if result := txn.Create(&scriptRecord); result.Error != nil {
356+
return fmt.Errorf("create plutus v3 script: %w", result.Error)
357+
}
358+
}
359+
360+
// Add PlutusData (Datums)
361+
for _, datum := range ws.PlutusData() {
362+
plutusData := models.PlutusData{
363+
TransactionID: tmpTx.ID,
364+
Data: datum.Cbor(),
365+
}
366+
if result := txn.Create(&plutusData); result.Error != nil {
367+
return fmt.Errorf("create plutus data: %w", result.Error)
368+
}
369+
}
370+
371+
// Add Redeemers
372+
if ws.Redeemers() != nil {
373+
for key, value := range ws.Redeemers().Iter() {
374+
redeemer := models.Redeemer{
375+
TransactionID: tmpTx.ID,
376+
Tag: uint8(key.Tag),
377+
Index: key.Index,
378+
Data: value.Data.Cbor(),
379+
ExUnitsMemory: uint64(value.ExUnits.Memory),
380+
ExUnitsCPU: uint64(value.ExUnits.Steps),
381+
}
382+
if result := txn.Create(&redeemer); result.Error != nil {
383+
return fmt.Errorf("create redeemer: %w", result.Error)
384+
}
385+
}
386+
}
387+
}
388+
280389
// Avoid updating associations
281390
result = txn.Omit(clause.Associations).Save(&tmpTx)
282391
if result.Error != nil {

0 commit comments

Comments
 (0)