Skip to content
Open
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions database/models/datum.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,15 @@ type Datum struct {
func (Datum) TableName() string {
return "datum"
}

// PlutusData represents a Plutus data value in the witness set
type PlutusData struct {
ID uint `gorm:"primaryKey"`
TransactionID uint `gorm:"index"`
Data []byte `gorm:"type:bytea"`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove the GORM field type override. This is a Postgres column type that won't work in SQLite

Transaction *Transaction
}

func (PlutusData) TableName() string {
return "plutus_data"
}
5 changes: 5 additions & 0 deletions database/models/models.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,21 @@ var MigrateModels = []any{
&DeregistrationDrep{},
&Drep{},
&Epoch{},
&KeyWitness{},
&Pool{},
&PoolRegistration{},
&PoolRegistrationOwner{},
&PoolRegistrationRelay{},
&PoolRetirement{},
&PParams{},
&PParamUpdate{},
&PlutusData{},
&Registration{},
&RegistrationDrep{},
&Redeemer{},
&ResignCommitteeCold{},
&Script{},
&ScriptContent{},
&StakeDelegation{},
&StakeDeregistration{},
&StakeRegistration{},
Expand Down
31 changes: 31 additions & 0 deletions database/models/redeemer.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Copyright 2025 Blink Labs Software
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package models

// Redeemer represents a redeemer in the witness set
type Redeemer struct {
ID uint `gorm:"primaryKey"`
TransactionID uint `gorm:"index"`
Tag uint8 `gorm:"index"` // Redeemer tag
Index uint32 `gorm:"index"`
Data []byte // Plutus data
ExUnitsMemory uint64
ExUnitsCPU uint64
Transaction *Transaction
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We probably don't want/need this reference back to Transaction when we've already got the TransactionId field

}

func (Redeemer) TableName() string {
return "redeemer"
}
37 changes: 37 additions & 0 deletions database/models/script.go
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rename this file to witness_script.go

Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// Copyright 2025 Blink Labs Software
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package models

// Script represents a reference to a script in the witness set
// Type corresponds to ScriptRefType constants from gouroboros/ledger/common:
// 0=NativeScript (ScriptRefTypeNativeScript)
// 1=PlutusV1 (ScriptRefTypePlutusV1)
// 2=PlutusV2 (ScriptRefTypePlutusV2)
// 3=PlutusV3 (ScriptRefTypePlutusV3)
//
// To avoid storing duplicate script data for the same script used in multiple
// transactions, we store only the script hash here. The actual script content
// is stored separately in ScriptContent table, indexed by hash.
type Script struct {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rename this to WitnessScripts to be a bit more specific about its function (mapping TX ID to script hash when the script appears in the TX witness)

ID uint `gorm:"primaryKey"`
TransactionID uint `gorm:"index"`
Type uint8 `gorm:"index"` // Script type
ScriptHash []byte `gorm:"index"` // Hash of the script
Transaction *Transaction
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We probably don't want/need this reference back to Transaction when we've already got the TransactionId field

}

func (Script) TableName() string {
return "script"
}
30 changes: 30 additions & 0 deletions database/models/script_content.go
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rename this file to script.go

Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Copyright 2025 Blink Labs Software
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package models

// ScriptContent represents the content of a script, indexed by its hash
// This avoids storing duplicate script data when the same script appears
// in multiple transactions
type ScriptContent struct {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rename this to Script

ID uint `gorm:"primaryKey"`
Hash []byte `gorm:"index;unique"` // Script hash
Type uint8 `gorm:"index"` // Script type
Content []byte // Script content
CreatedSlot uint64 // Slot when this script was first seen
}

func (ScriptContent) TableName() string {
return "script_content"
}
20 changes: 12 additions & 8 deletions database/models/transaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,18 @@ package models

// Transaction represents a transaction record
type Transaction struct {
Hash []byte `gorm:"uniqueIndex"`
BlockHash []byte `gorm:"index"`
Inputs []Utxo `gorm:"foreignKey:SpentAtTxId;references:Hash"`
Outputs []Utxo `gorm:"foreignKey:TransactionID;references:ID"`
ReferenceInputs []Utxo `gorm:"foreignKey:ReferencedByTxId;references:Hash"`
Collateral []Utxo `gorm:"foreignKey:CollateralByTxId;references:Hash"`
CollateralReturn *Utxo `gorm:"foreignKey:TransactionID;references:ID"`
ID uint `gorm:"primaryKey"`
Hash []byte `gorm:"uniqueIndex"`
BlockHash []byte `gorm:"index"`
Inputs []Utxo `gorm:"foreignKey:SpentAtTxId;references:Hash"`
Outputs []Utxo `gorm:"foreignKey:TransactionID;references:ID"`
ReferenceInputs []Utxo `gorm:"foreignKey:ReferencedByTxId;references:Hash"`
Collateral []Utxo `gorm:"foreignKey:CollateralByTxId;references:Hash"`
CollateralReturn *Utxo `gorm:"foreignKey:TransactionID;references:ID"`
KeyWitnesses []KeyWitness `gorm:"foreignKey:TransactionID;references:ID"`
Scripts []Script `gorm:"foreignKey:TransactionID;references:ID"`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rename to WitnessScripts

Redeemers []Redeemer `gorm:"foreignKey:TransactionID;references:ID"`
PlutusData []PlutusData `gorm:"foreignKey:TransactionID;references:ID"`
ID uint `gorm:"primaryKey"`
Type int
BlockIndex uint32
Metadata []byte
Expand Down
40 changes: 40 additions & 0 deletions database/models/witness.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// Copyright 2025 Blink Labs Software
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package models

const (
// KeyWitnessTypeVkey represents a Vkey witness
KeyWitnessTypeVkey uint8 = iota
// KeyWitnessTypeBootstrap represents a Bootstrap witness
KeyWitnessTypeBootstrap
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Be explicit with the values here. It's generally a bad idea to use iota in cases where the value can persist between older and newer versions of the code in case values are added/removed.

)

// KeyWitness represents a key witness entry (Vkey or Bootstrap)
// Type: KeyWitnessTypeVkey = VkeyWitness, KeyWitnessTypeBootstrap = BootstrapWitness
type KeyWitness struct {
ID uint `gorm:"primaryKey"`
TransactionID uint `gorm:"index"`
Type uint8 `gorm:"index"` // See KeyWitnessType* constants
Vkey []byte // Vkey witness key
Signature []byte // Witness signature
PublicKey []byte // For Bootstrap witness
ChainCode []byte // For Bootstrap witness
Attributes []byte // For Bootstrap witness
Transaction *Transaction
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We probably don't want/need this reference back to Transaction when we've already got the TransactionId field

}

func (KeyWitness) TableName() string {
return "key_witness"
}
58 changes: 58 additions & 0 deletions database/plugin/metadata/sqlite/script.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
// Copyright 2025 Blink Labs Software
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package sqlite

import (
"errors"

"github.com/blinklabs-io/dingo/database/models"
lcommon "github.com/blinklabs-io/gouroboros/ledger/common"
"gorm.io/gorm"
)

// GetScriptContent returns the script content by its hash
func (d *MetadataStoreSqlite) GetScriptContent(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rename this to GetScript

hash lcommon.ScriptHash,
txn *gorm.DB,
) (*models.ScriptContent, error) {
ret := &models.ScriptContent{}
if txn == nil {
txn = d.DB()
}
result := txn.First(ret, "hash = ?", hash[:])
if result.Error != nil {
if errors.Is(result.Error, gorm.ErrRecordNotFound) {
return nil, nil
}
return nil, result.Error
}
return ret, nil
}

// GetScriptsByTransaction returns all scripts (references) used in a particular transaction
func (d *MetadataStoreSqlite) GetScriptsByTransaction(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GetScriptWitnessesByTransaction

But is this even needed? We probably don't need to query script witnesses for a particular TX without querying for the entire TX, which will include that data.

txID uint,
txn *gorm.DB,
) ([]models.Script, error) {
var scripts []models.Script
if txn == nil {
txn = d.DB()
}
result := txn.Where("transaction_id = ?", txID).Find(&scripts)
if result.Error != nil {
return nil, result.Error
}
return scripts, nil
}
Loading
Loading