Skip to content

Commit 149769e

Browse files
committed
feat: support for certificates in plutus script context
* implement ToPlutusData() for common.Drep * rename stake registration/deregistration field for consistency * support for certificates and treasury amount/donation in TxInfoV3 * port Aiken script_context_certificates test Fixes #1102 Signed-off-by: Aurora Gaffney <[email protected]>
1 parent 8bd1ca1 commit 149769e

File tree

12 files changed

+270
-46
lines changed

12 files changed

+270
-46
lines changed

internal/test/ledger/ledger.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ func (ls MockLedgerState) StakeRegistration(
5252
ret := []common.StakeRegistrationCertificate{}
5353
for _, cert := range ls.MockStakeRegistration {
5454
if string(
55-
common.Blake2b224(cert.StakeRegistration.Credential).Bytes(),
55+
common.Blake2b224(cert.StakeCredential.Credential).Bytes(),
5656
) == string(
5757
stakingKey,
5858
) {

ledger/allegra/rules_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -554,7 +554,7 @@ func TestUtxoValidateValueNotConservedUtxo(t *testing.T) {
554554
{
555555
Type: common.CertificateTypeStakeRegistration,
556556
Certificate: &common.StakeRegistrationCertificate{
557-
StakeRegistration: common.Credential{},
557+
StakeCredential: common.Credential{},
558558
},
559559
},
560560
}
@@ -581,7 +581,7 @@ func TestUtxoValidateValueNotConservedUtxo(t *testing.T) {
581581
{
582582
Type: common.CertificateTypeStakeRegistration,
583583
Certificate: &common.StakeDeregistrationCertificate{
584-
StakeDeregistration: common.Credential{},
584+
StakeCredential: common.Credential{},
585585
},
586586
},
587587
}

ledger/alonzo/rules_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -563,7 +563,7 @@ func TestUtxoValidateValueNotConservedUtxo(t *testing.T) {
563563
{
564564
Type: common.CertificateTypeStakeRegistration,
565565
Certificate: &common.StakeRegistrationCertificate{
566-
StakeRegistration: common.Credential{},
566+
StakeCredential: common.Credential{},
567567
},
568568
},
569569
}
@@ -590,7 +590,7 @@ func TestUtxoValidateValueNotConservedUtxo(t *testing.T) {
590590
{
591591
Type: common.CertificateTypeStakeRegistration,
592592
Certificate: &common.StakeDeregistrationCertificate{
593-
StakeDeregistration: common.Credential{},
593+
StakeCredential: common.Credential{},
594594
},
595595
},
596596
}

ledger/babbage/rules_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -564,7 +564,7 @@ func TestUtxoValidateValueNotConservedUtxo(t *testing.T) {
564564
{
565565
Type: common.CertificateTypeStakeRegistration,
566566
Certificate: &common.StakeRegistrationCertificate{
567-
StakeRegistration: common.Credential{},
567+
StakeCredential: common.Credential{},
568568
},
569569
},
570570
}
@@ -591,7 +591,7 @@ func TestUtxoValidateValueNotConservedUtxo(t *testing.T) {
591591
{
592592
Type: common.CertificateTypeStakeRegistration,
593593
Certificate: &common.StakeDeregistrationCertificate{
594-
StakeDeregistration: common.Credential{},
594+
StakeCredential: common.Credential{},
595595
},
596596
},
597597
}

ledger/common/certs.go

Lines changed: 36 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import (
2222
"net"
2323

2424
"github.com/blinklabs-io/gouroboros/cbor"
25+
"github.com/blinklabs-io/plutigo/data"
2526
utxorpc "github.com/utxorpc/go-codegen/utxorpc/v1alpha/cardano"
2627
)
2728

@@ -159,11 +160,37 @@ func (d *Drep) UnmarshalCBOR(data []byte) error {
159160
return nil
160161
}
161162

163+
func (d *Drep) ToPlutusData() data.PlutusData {
164+
switch d.Type {
165+
case DrepTypeAddrKeyHash:
166+
return data.NewConstr(
167+
0,
168+
data.NewConstr(
169+
0,
170+
data.NewByteString(d.Credential),
171+
),
172+
)
173+
case DrepTypeScriptHash:
174+
return data.NewConstr(
175+
0,
176+
data.NewConstr(
177+
1,
178+
data.NewByteString(d.Credential),
179+
),
180+
)
181+
case DrepTypeAbstain:
182+
return data.NewConstr(1)
183+
case DrepTypeNoConfidence:
184+
return data.NewConstr(2)
185+
}
186+
return nil
187+
}
188+
162189
type StakeRegistrationCertificate struct {
163190
cbor.StructAsArray
164191
cbor.DecodeStoreCbor
165-
CertType uint
166-
StakeRegistration Credential
192+
CertType uint
193+
StakeCredential Credential
167194
}
168195

169196
func (c StakeRegistrationCertificate) isCertificate() {}
@@ -180,7 +207,7 @@ func (c *StakeRegistrationCertificate) UnmarshalCBOR(cborData []byte) error {
180207
}
181208

182209
func (c *StakeRegistrationCertificate) Utxorpc() (*utxorpc.Certificate, error) {
183-
stakeCred, err := c.StakeRegistration.Utxorpc()
210+
stakeCred, err := c.StakeCredential.Utxorpc()
184211
if err != nil {
185212
return nil, err
186213
}
@@ -198,8 +225,8 @@ func (c *StakeRegistrationCertificate) Type() uint {
198225
type StakeDeregistrationCertificate struct {
199226
cbor.StructAsArray
200227
cbor.DecodeStoreCbor
201-
CertType uint
202-
StakeDeregistration Credential
228+
CertType uint
229+
StakeCredential Credential
203230
}
204231

205232
func (c StakeDeregistrationCertificate) isCertificate() {}
@@ -216,7 +243,7 @@ func (c *StakeDeregistrationCertificate) UnmarshalCBOR(cborData []byte) error {
216243
}
217244

218245
func (c *StakeDeregistrationCertificate) Utxorpc() (*utxorpc.Certificate, error) {
219-
stakeDeReg, err := c.StakeDeregistration.Utxorpc()
246+
stakeDeReg, err := c.StakeCredential.Utxorpc()
220247
if err != nil {
221248
return nil, err
222249
}
@@ -1081,7 +1108,7 @@ type AuthCommitteeHotCertificate struct {
10811108
cbor.DecodeStoreCbor
10821109
CertType uint
10831110
ColdCredential Credential
1084-
HostCredential Credential
1111+
HotCredential Credential
10851112
}
10861113

10871114
func (c AuthCommitteeHotCertificate) isCertificate() {}
@@ -1104,15 +1131,15 @@ func (c *AuthCommitteeHotCertificate) Utxorpc() (*utxorpc.Certificate, error) {
11041131
if err != nil {
11051132
return nil, err
11061133
}
1107-
hostCred, err := c.HostCredential.Utxorpc()
1134+
hotCred, err := c.HotCredential.Utxorpc()
11081135
if err != nil {
11091136
return nil, err
11101137
}
11111138
return &utxorpc.Certificate{
11121139
Certificate: &utxorpc.Certificate_AuthCommitteeHotCert{
11131140
AuthCommitteeHotCert: &utxorpc.AuthCommitteeHotCert{
11141141
CommitteeColdCredential: coldCred,
1115-
CommitteeHotCredential: hostCred,
1142+
CommitteeHotCredential: hotCred,
11161143
},
11171144
},
11181145
}, nil

ledger/common/script/context.go

Lines changed: 157 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -153,8 +153,7 @@ func (t TxInfoV3) ToPlutusData() data.PlutusData {
153153
toPlutusData(t.Outputs),
154154
data.NewInteger(new(big.Int).SetUint64(t.Fee)),
155155
t.Mint.ToPlutusData(),
156-
// TODO: certs
157-
toPlutusData([]any{}),
156+
certificatesToPlutusData(t.Certificates),
158157
toPlutusData(t.Withdrawals),
159158
t.ValidRange.ToPlutusData(),
160159
toPlutusData(t.Signatories),
@@ -165,10 +164,8 @@ func (t TxInfoV3) ToPlutusData() data.PlutusData {
165164
data.NewMap([][2]data.PlutusData{}),
166165
// TODO: proposal procedures
167166
toPlutusData([]any{}),
168-
// TODO: current treasury amount
169-
data.NewConstr(1),
170-
// TODO: treasury donation
171-
data.NewConstr(1),
167+
t.CurrentTreasuryAmount.ToPlutusData(),
168+
t.TreasuryDonation.ToPlutusData(),
172169
)
173170
}
174171

@@ -187,7 +184,7 @@ func NewTxInfoV3FromTransaction(
187184
resolvedInputs,
188185
inputs,
189186
*assetMint,
190-
// TODO: certificates
187+
tx.Certificates(),
191188
tx.Withdrawals(),
192189
// TODO: proposal procedures
193190
// TODO: votes
@@ -207,15 +204,20 @@ func NewTxInfoV3FromTransaction(
207204
tx.TTL(),
208205
tx.ValidityIntervalStart(),
209206
},
210-
Withdrawals: tx.Withdrawals(),
211-
Signatories: signatoriesInfo(tx.RequiredSigners()),
212-
Redeemers: redeemers,
213-
Data: tmpData,
214-
Id: tx.Hash(),
207+
Certificates: tx.Certificates(),
208+
Withdrawals: tx.Withdrawals(),
209+
Signatories: signatoriesInfo(tx.RequiredSigners()),
210+
Redeemers: redeemers,
211+
Data: tmpData,
212+
Id: tx.Hash(),
215213
// TODO: Votes
216214
// TODO: ProposalProcedures
217-
// TODO: CurrentTreasuryAmount
218-
// TODO: TreasuryDonation
215+
}
216+
if amt := tx.CurrentTreasuryValue(); amt > 0 {
217+
ret.CurrentTreasuryAmount.Value = amt
218+
}
219+
if amt := tx.Donation(); amt > 0 {
220+
ret.TreasuryDonation.Value = amt
219221
}
220222
return ret
221223
}
@@ -396,3 +398,144 @@ func signatoriesInfo(
396398
)
397399
return tmp
398400
}
401+
402+
func certificatesToPlutusData(
403+
certificates []lcommon.Certificate,
404+
) data.PlutusData {
405+
tmpCerts := make([]data.PlutusData, len(certificates))
406+
for idx, cert := range certificates {
407+
tmpCerts[idx] = certificateToPlutusData(cert)
408+
}
409+
return data.NewList(tmpCerts...)
410+
}
411+
412+
func certificateToPlutusData(
413+
certificate lcommon.Certificate,
414+
) data.PlutusData {
415+
switch c := certificate.(type) {
416+
case *lcommon.StakeRegistrationCertificate:
417+
return data.NewConstr(
418+
0,
419+
c.StakeCredential.ToPlutusData(),
420+
data.NewConstr(1),
421+
)
422+
case *lcommon.RegistrationCertificate:
423+
return data.NewConstr(
424+
0,
425+
c.StakeCredential.ToPlutusData(),
426+
data.NewConstr(1),
427+
)
428+
case *lcommon.StakeDeregistrationCertificate:
429+
return data.NewConstr(
430+
1,
431+
c.StakeCredential.ToPlutusData(),
432+
data.NewConstr(1),
433+
)
434+
case *lcommon.DeregistrationCertificate:
435+
return data.NewConstr(
436+
1,
437+
c.StakeCredential.ToPlutusData(),
438+
data.NewConstr(1),
439+
)
440+
case *lcommon.StakeDelegationCertificate:
441+
return data.NewConstr(
442+
2,
443+
c.StakeCredential.ToPlutusData(),
444+
data.NewConstr(
445+
0,
446+
c.PoolKeyHash.ToPlutusData(),
447+
),
448+
)
449+
case *lcommon.VoteDelegationCertificate:
450+
return data.NewConstr(
451+
2,
452+
c.StakeCredential.ToPlutusData(),
453+
data.NewConstr(
454+
1,
455+
c.Drep.ToPlutusData(),
456+
),
457+
)
458+
case *lcommon.StakeVoteDelegationCertificate:
459+
return data.NewConstr(
460+
2,
461+
c.StakeCredential.ToPlutusData(),
462+
data.NewConstr(
463+
2,
464+
toPlutusData(c.PoolKeyHash),
465+
c.Drep.ToPlutusData(),
466+
),
467+
)
468+
case *lcommon.StakeRegistrationDelegationCertificate:
469+
return data.NewConstr(
470+
3,
471+
c.StakeCredential.ToPlutusData(),
472+
data.NewConstr(
473+
0,
474+
toPlutusData(c.PoolKeyHash),
475+
),
476+
data.NewInteger(big.NewInt(c.Amount)),
477+
)
478+
case *lcommon.VoteRegistrationDelegationCertificate:
479+
return data.NewConstr(
480+
3,
481+
c.StakeCredential.ToPlutusData(),
482+
data.NewConstr(
483+
1,
484+
c.Drep.ToPlutusData(),
485+
),
486+
data.NewInteger(big.NewInt(c.Amount)),
487+
)
488+
case *lcommon.StakeVoteRegistrationDelegationCertificate:
489+
return data.NewConstr(
490+
3,
491+
c.StakeCredential.ToPlutusData(),
492+
data.NewConstr(
493+
2,
494+
c.PoolKeyHash.ToPlutusData(),
495+
c.Drep.ToPlutusData(),
496+
),
497+
data.NewInteger(big.NewInt(c.Amount)),
498+
)
499+
case *lcommon.RegistrationDrepCertificate:
500+
return data.NewConstr(
501+
4,
502+
c.DrepCredential.ToPlutusData(),
503+
data.NewInteger(big.NewInt(c.Amount)),
504+
)
505+
case *lcommon.UpdateDrepCertificate:
506+
return data.NewConstr(
507+
5,
508+
c.DrepCredential.ToPlutusData(),
509+
)
510+
case *lcommon.DeregistrationDrepCertificate:
511+
return data.NewConstr(
512+
6,
513+
c.DrepCredential.ToPlutusData(),
514+
data.NewInteger(big.NewInt(c.Amount)),
515+
)
516+
case *lcommon.PoolRegistrationCertificate:
517+
return data.NewConstr(
518+
7,
519+
toPlutusData(c.Operator),
520+
toPlutusData(c.VrfKeyHash),
521+
)
522+
case *lcommon.PoolRetirementCertificate:
523+
return data.NewConstr(
524+
8,
525+
toPlutusData(c.PoolKeyHash),
526+
data.NewInteger(new(big.Int).SetUint64(c.Epoch)),
527+
)
528+
case *lcommon.AuthCommitteeHotCertificate:
529+
return data.NewConstr(
530+
9,
531+
c.ColdCredential.ToPlutusData(),
532+
c.HotCredential.ToPlutusData(),
533+
)
534+
case *lcommon.ResignCommitteeColdCertificate:
535+
return data.NewConstr(
536+
10,
537+
c.ColdCredential.ToPlutusData(),
538+
)
539+
}
540+
return nil
541+
}

ledger/common/script/context_test.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,15 @@ var scriptContextV3TestDefs = []struct {
186186
redeemerIndex: 0,
187187
expectedCbor: "d8799fd8799f9fd8799fd8799f5820c9f355431b2546acfc03b11540dc8bee31b9afc5674081a61cc39e0845380e7a00ffd8799fd8799fd87a9f581cfdd6640d1c9a4392dd7e829f0cc4e26766539c48b2cf594959e33559ffd87a80ffa140a1401a00989680d87b9fd8799f581c9fc430ea1f3adc20eebb813b2649e85c934ea5bc13d7b7fbe2b24e50ffffd8799f581cfdd6640d1c9a4392dd7e829f0cc4e26766539c48b2cf594959e33559ffffffff9fd8799fd8799f58204f184460ae3f3c15c6811f1380c3abc7bb73bf3cbbdffe874913c2410fc3577600ffd8799fd8799fd87a9f581cfdd6640d1c9a4392dd7e829f0cc4e26766539c48b2cf594959e33559ffd87a80ffa140a1401a00989680d87b9fd8799f581c86b74c779bb9cf43532b357323b0ced1bdd6aa4276c45aee845f33feffffd8799f581cfdd6640d1c9a4392dd7e829f0cc4e26766539c48b2cf594959e33559ffffffff9fd8799fd8799fd8799f581c9fc430ea1f3adc20eebb813b2649e85c934ea5bc13d7b7fbe2b24e50ffd8799fd8799fd8799f581c5064b671634d14cb8d543e71dd8eb437a47efb47b0b22882866c420dffffffffa140a1401a009569e4d87980d87a80ffff1a00032c9ca080a0d8799fd8799fd87980d87a80ffd8799fd87b80d87a80ffff9f581c9fc430ea1f3adc20eebb813b2649e85c934ea5bc13d7b7fbe2b24e50ffa1d87a9fd8799f5820c9f355431b2546acfc03b11540dc8bee31b9afc5674081a61cc39e0845380e7a00ffffd8799f4d48656c6c6f2c20576f726c6421ffa05820ac73d6545da30a8cc0395de0c2a5fa3ad99329f41d319901ebe2922f8554d5e3a080d87a80d87a80ffd8799f4d48656c6c6f2c20576f726c6421ffd87a9fd8799f5820c9f355431b2546acfc03b11540dc8bee31b9afc5674081a61cc39e0845380e7a00ffd8799fd8799f581c9fc430ea1f3adc20eebb813b2649e85c934ea5bc13d7b7fbe2b24e50ffffffff",
188188
},
189+
{
190+
name: "Certificates",
191+
txHex: "84a600818258200000000000000000000000000000000000000000000000000000000000000000000180049582008201581c2222222222222222222222222222222222222222222222222222222282008200581c0000000000000000000000000000000000000000000000000000000082018200581c000000000000000000000000000000000000000000000000000000008a03581c11111111111111111111111111111111111111111111111111111111582099999999999999999999999999999999999999999999999999999999999999991a000f4240190154d81e82011864581de000000000000000000000000000000000000000000000000000000000d901028080f68304581c1111111111111111111111111111111111111111111111111111111119053983078200581c000000000000000000000000000000000000000000000000000000001a002dc6c083088200581c000000000000000000000000000000000000000000000000000000001a002dc6c083098200581c000000000000000000000000000000000000000000000000000000008200581c0000000000000000000000000000000000000000000000000000000083098200581c000000000000000000000000000000000000000000000000000000008201581c0000000000000000000000000000000000000000000000000000000083098200581c00000000000000000000000000000000000000000000000000000000810283098200581c000000000000000000000000000000000000000000000000000000008103840a8200581c00000000000000000000000000000000000000000000000000000000581c111111111111111111111111111111111111111111111111111111118103840b8200581c00000000000000000000000000000000000000000000000000000000581c111111111111111111111111111111111111111111111111111111111a002dc6c0840c8200581c0000000000000000000000000000000000000000000000000000000081031a002dc6c0850d8200581c00000000000000000000000000000000000000000000000000000000581c1111111111111111111111111111111111111111111111111111111181031a002dc6c0830e8200581c000000000000000000000000000000000000000000000000000000008200581c22222222222222222222222222222222222222222222222222222222830f8200581c00000000000000000000000000000000000000000000000000000000f684108200581c000000000000000000000000000000000000000000000000000000001a002dc6c0f683118200581c000000000000000000000000000000000000000000000000000000001a002dc6c083128200581c00000000000000000000000000000000000000000000000000000000f683028201581c9b24324046544393443e1fb35c8b72c3c39e18a516a95df5f6654101581c1111111111111111111111111111111111111111111111111111111102182a151a00989680160ea20581840214d87980821a000f42401a05f5e1000781587d587b0101003232323232323225333333008001153330033370e900018029baa001153330073006375400224a66600894452615330054911856616c696461746f722072657475726e65642066616c73650013656002002002002002002153300249010b5f746d70313a20566f696400165734ae7155ceaab9e5573eae91f5f6",
192+
inputsHex: "81825820000000000000000000000000000000000000000000000000000000000000000000",
193+
outputsHex: "81a200581d6000000000000000000000000000000000000000000000000000000000011a000f4240",
194+
redeemerTag: common.RedeemerTagCert,
195+
redeemerIndex: 20,
196+
expectedCbor: "d8799fd8799f9fd8799fd8799f5820000000000000000000000000000000000000000000000000000000000000000000ffd8799fd8799fd8799f581c00000000000000000000000000000000000000000000000000000000ffd87a80ffa140a1401a000f4240d87980d87a80ffffff8080182aa09fd8799fd87a9f581c22222222222222222222222222222222222222222222222222222222ffd87a80ffd8799fd8799f581c00000000000000000000000000000000000000000000000000000000ffd87a80ffd87a9fd8799f581c00000000000000000000000000000000000000000000000000000000ffd87a80ffd905009f581c1111111111111111111111111111111111111111111111111111111158209999999999999999999999999999999999999999999999999999999999999999ffd905019f581c11111111111111111111111111111111111111111111111111111111190539ffd8799fd8799f581c00000000000000000000000000000000000000000000000000000000ffd87a80ffd87a9fd8799f581c00000000000000000000000000000000000000000000000000000000ffd87a80ffd87b9fd8799f581c00000000000000000000000000000000000000000000000000000000ffd87a9fd8799fd8799f581c00000000000000000000000000000000000000000000000000000000ffffffffd87b9fd8799f581c00000000000000000000000000000000000000000000000000000000ffd87a9fd8799fd87a9f581c00000000000000000000000000000000000000000000000000000000ffffffffd87b9fd8799f581c00000000000000000000000000000000000000000000000000000000ffd87a9fd87a80ffffd87b9fd8799f581c00000000000000000000000000000000000000000000000000000000ffd87a9fd87b80ffffd87b9fd8799f581c00000000000000000000000000000000000000000000000000000000ffd87b9f581c11111111111111111111111111111111111111111111111111111111d87b80ffffd87c9fd8799f581c00000000000000000000000000000000000000000000000000000000ffd8799f581c11111111111111111111111111111111111111111111111111111111ff1a002dc6c0ffd87c9fd8799f581c00000000000000000000000000000000000000000000000000000000ffd87a9fd87b80ff1a002dc6c0ffd87c9fd8799f581c00000000000000000000000000000000000000000000000000000000ffd87b9f581c11111111111111111111111111111111111111111111111111111111d87b80ff1a002dc6c0ffd905029fd8799f581c00000000000000000000000000000000000000000000000000000000ffd8799f581c22222222222222222222222222222222222222222222222222222222ffffd905039fd8799f581c00000000000000000000000000000000000000000000000000000000ffffd87d9fd8799f581c00000000000000000000000000000000000000000000000000000000ff1a002dc6c0ffd87f9fd8799f581c00000000000000000000000000000000000000000000000000000000ff1a002dc6c0ffd87e9fd8799f581c00000000000000000000000000000000000000000000000000000000ffffd87b9fd87a9f581c9b24324046544393443e1fb35c8b72c3c39e18a516a95df5f6654101ffd8799f581c11111111111111111111111111111111111111111111111111111111ffffffa0d8799fd8799fd87980d87a80ffd8799fd87b80d87a80ffff80a1d87c9f14d87b9fd87a9f581c9b24324046544393443e1fb35c8b72c3c39e18a516a95df5f6654101ffd8799f581c11111111111111111111111111111111111111111111111111111111ffffffd87980a0582080bf68ced2c50b8734fc8cebd0a049e16e53d2fe5ec7e42822f07c263ced98aba080d8799f1a00989680ffd8799f0effffd87980d87c9f14d87b9fd87a9f581c9b24324046544393443e1fb35c8b72c3c39e18a516a95df5f6654101ffd8799f581c11111111111111111111111111111111111111111111111111111111ffffffff",
197+
},
189198
}
190199

191200
func TestScriptContextV3(t *testing.T) {

0 commit comments

Comments
 (0)