Skip to content

Commit 78c8ece

Browse files
authored
feat(database): Track transaction Datum (#1053)
Signed-off-by: Akhil Repala <arepala@blinklabs.io>
1 parent 040e5f2 commit 78c8ece

File tree

3 files changed

+87
-0
lines changed

3 files changed

+87
-0
lines changed

database/datum.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@
1515
package database
1616

1717
import (
18+
"errors"
19+
20+
"github.com/blinklabs-io/dingo/database/models"
1821
lcommon "github.com/blinklabs-io/gouroboros/ledger/common"
1922
)
2023

@@ -33,3 +36,26 @@ func (d *Database) SetDatum(
3336
}
3437
return d.metadata.SetDatum(datumHash, rawDatum, addedSlot, txn.Metadata())
3538
}
39+
40+
// GetDatum retrieves a datum by its hash.
41+
func (d *Database) GetDatum(
42+
hash []byte,
43+
txn *Txn,
44+
) (*models.Datum, error) {
45+
if len(hash) == 0 {
46+
return nil, errors.New("datum not found")
47+
}
48+
if txn == nil {
49+
txn = d.Transaction(false)
50+
defer txn.Commit() //nolint:errcheck
51+
}
52+
tmpHash := lcommon.NewBlake2b256(hash)
53+
ret, err := d.metadata.GetDatum(tmpHash, txn.Metadata())
54+
if err != nil {
55+
return nil, err
56+
}
57+
if ret == nil {
58+
return nil, errors.New("datum not found")
59+
}
60+
return ret, nil
61+
}

database/plugin/metadata/sqlite/transaction.go

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -752,5 +752,61 @@ func (d *MetadataStoreSqlite) SetTransaction(
752752
}
753753
}
754754

755+
if err := d.storeTransactionDatums(tx, point.Slot, txn); err != nil {
756+
return fmt.Errorf("store datums failed: %w", err)
757+
}
758+
759+
return nil
760+
}
761+
762+
// Traverse each utxo and check for inline datum & calls storeDatum
763+
func (d *MetadataStoreSqlite) storeTransactionDatums(
764+
tx lcommon.Transaction,
765+
slot uint64,
766+
txn *gorm.DB,
767+
) error {
768+
for _, utxo := range tx.Produced() {
769+
if err := d.storeDatum(utxo.Output.Datum(), slot, txn); err != nil {
770+
return err
771+
}
772+
}
773+
witnesses := tx.Witnesses()
774+
if witnesses == nil {
775+
return nil
776+
}
777+
// Looks over the transaction witness set & store each datum.
778+
for _, datum := range witnesses.PlutusData() {
779+
datumCopy := datum
780+
if err := d.storeDatum(&datumCopy, slot, txn); err != nil {
781+
return err
782+
}
783+
}
784+
return nil
785+
}
786+
787+
// Marshal the raw CBOR and hashes with Blake2b256Hash & calls SetDatum of metadata store.
788+
func (d *MetadataStoreSqlite) storeDatum(
789+
datum *lcommon.Datum,
790+
slot uint64,
791+
txn *gorm.DB,
792+
) error {
793+
if datum == nil {
794+
return nil
795+
}
796+
rawDatum := datum.Cbor()
797+
if len(rawDatum) == 0 {
798+
var err error
799+
rawDatum, err = datum.MarshalCBOR()
800+
if err != nil {
801+
return fmt.Errorf("marshal datum: %w", err)
802+
}
803+
}
804+
if len(rawDatum) == 0 {
805+
return nil
806+
}
807+
datumHash := lcommon.Blake2b256Hash(rawDatum)
808+
if err := d.SetDatum(datumHash, rawDatum, slot, txn); err != nil {
809+
return err
810+
}
755811
return nil
756812
}

ledger/state.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,11 @@ func (ls *LedgerState) Chain() *chain.Chain {
195195
return ls.chain
196196
}
197197

198+
// Datum looks up a datum by hash & adding this for implementing query.ReadData #741
199+
func (ls *LedgerState) Datum(hash []byte) (*models.Datum, error) {
200+
return ls.db.GetDatum(hash, nil)
201+
}
202+
198203
func (ls *LedgerState) Close() error {
199204
return ls.db.Close()
200205
}

0 commit comments

Comments
 (0)