Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
144 changes: 56 additions & 88 deletions ledger/common/gov.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
package common

import (
"fmt"
"math/big"

"github.com/blinklabs-io/gouroboros/cbor"
Expand Down Expand Up @@ -129,21 +128,19 @@ func (id *GovActionId) ToPlutusData() data.PlutusData {
)
}

type ProposalProcedure struct {
cbor.StructAsArray
Deposit uint64
RewardAccount Address
GovAction GovActionWrapper
Anchor GovAnchor
type ProposalProcedure interface {
isProposalProcedure()
ToPlutusData() data.PlutusData
Deposit() uint64
RewardAccount() Address
GovAction() GovAction
Anchor() GovAnchor
}

func (p *ProposalProcedure) ToPlutusData() data.PlutusData {
return data.NewConstr(0,
data.NewInteger(new(big.Int).SetUint64(p.Deposit)),
p.RewardAccount.ToPlutusData(),
p.GovAction.ToPlutusData(),
)
}
type ProposalProcedureBase struct{}

// nolint:unused
func (ProposalProcedureBase) isProposalProcedure() {}

const (
GovActionTypeParameterChange = 0
Expand All @@ -155,76 +152,15 @@ const (
GovActionTypeInfo = 6
)

type GovActionWrapper struct {
Type uint
Action GovAction
}

func (g *GovActionWrapper) ToPlutusData() data.PlutusData {
return g.Action.ToPlutusData()
}

func (g *GovActionWrapper) UnmarshalCBOR(data []byte) error {
// Determine action type
actionType, err := cbor.DecodeIdFromList(data)
if err != nil {
return err
}
var tmpAction GovAction
switch actionType {
case GovActionTypeParameterChange:
tmpAction = &ParameterChangeGovAction{}
case GovActionTypeHardForkInitiation:
tmpAction = &HardForkInitiationGovAction{}
case GovActionTypeTreasuryWithdrawal:
tmpAction = &TreasuryWithdrawalGovAction{}
case GovActionTypeNoConfidence:
tmpAction = &NoConfidenceGovAction{}
case GovActionTypeUpdateCommittee:
tmpAction = &UpdateCommitteeGovAction{}
case GovActionTypeNewConstitution:
tmpAction = &NewConstitutionGovAction{}
case GovActionTypeInfo:
tmpAction = &InfoGovAction{}
default:
return fmt.Errorf("unknown governance action type: %d", actionType)
}
// Decode action
if _, err := cbor.Decode(data, tmpAction); err != nil {
return err
}
// action type is known within uint range
g.Type = uint(actionType) // #nosec G115
g.Action = tmpAction
return nil
}

func (g *GovActionWrapper) MarshalCBOR() ([]byte, error) {
return cbor.Encode(g.Action)
}

type GovAction interface {
isGovAction()
ToPlutusData() data.PlutusData
}

type ParameterChangeGovAction struct {
cbor.StructAsArray
Type uint
ActionId *GovActionId
ParamUpdate cbor.RawMessage // NOTE: we use raw to defer processing to account for per-era types
PolicyHash []byte
}

func (a *ParameterChangeGovAction) ToPlutusData() data.PlutusData {
return data.NewConstr(0,
a.ActionId.ToPlutusData(),
data.NewByteString(a.ParamUpdate),
data.NewByteString(a.PolicyHash),
)
}
type GovActionBase struct{}

func (a ParameterChangeGovAction) isGovAction() {}
// nolint:unused
func (GovActionBase) isGovAction() {}

type HardForkInitiationGovAction struct {
cbor.StructAsArray
Expand All @@ -238,8 +174,12 @@ type HardForkInitiationGovAction struct {
}

func (a *HardForkInitiationGovAction) ToPlutusData() data.PlutusData {
actionId := data.NewConstr(1)
if a.ActionId != nil {
actionId = data.NewConstr(0, a.ActionId.ToPlutusData())
}
return data.NewConstr(1,
a.ActionId.ToPlutusData(),
actionId,
data.NewConstr(
0,
data.NewInteger(
Expand All @@ -265,13 +205,20 @@ func (a *TreasuryWithdrawalGovAction) ToPlutusData() data.PlutusData {
pairs := make([][2]data.PlutusData, 0, len(a.Withdrawals))
for addr, amount := range a.Withdrawals {
pairs = append(pairs, [2]data.PlutusData{
data.NewConstr(0, addr.ToPlutusData()),
addr.ToPlutusData(),
data.NewInteger(new(big.Int).SetUint64(amount)),
})
}
policyHash := data.NewConstr(1)
if len(a.PolicyHash) > 0 {
policyHash = data.NewConstr(
0,
data.NewByteString(a.PolicyHash),
)
}
return data.NewConstr(2,
data.NewMap(pairs),
data.NewByteString(a.PolicyHash),
policyHash,
)
}

Expand All @@ -284,8 +231,12 @@ type NoConfidenceGovAction struct {
}

func (a *NoConfidenceGovAction) ToPlutusData() data.PlutusData {
actionId := data.NewConstr(1)
if a.ActionId != nil {
actionId = data.NewConstr(0, a.ActionId.ToPlutusData())
}
return data.NewConstr(3,
a.ActionId.ToPlutusData(),
actionId,
)
}

Expand All @@ -301,6 +252,10 @@ type UpdateCommitteeGovAction struct {
}

func (a *UpdateCommitteeGovAction) ToPlutusData() data.PlutusData {
actionId := data.NewConstr(1)
if a.ActionId != nil {
actionId = data.NewConstr(0, a.ActionId.ToPlutusData())
}
removedItems := make([]data.PlutusData, 0, len(a.Credentials))
for _, cred := range a.Credentials {
removedItems = append(removedItems, cred.ToPlutusData())
Expand All @@ -325,11 +280,14 @@ func (a *UpdateCommitteeGovAction) ToPlutusData() data.PlutusData {
}

return data.NewConstr(4,
a.ActionId.ToPlutusData(),
actionId,
data.NewList(removedItems...),
data.NewMap(addedPairs),
data.NewInteger(num),
data.NewInteger(den),
data.NewConstr(
0,
data.NewInteger(num),
data.NewInteger(den),
),
)
}

Expand All @@ -347,11 +305,21 @@ type NewConstitutionGovAction struct {
}

func (a *NewConstitutionGovAction) ToPlutusData() data.PlutusData {
actionId := data.NewConstr(1)
if a.ActionId != nil {
actionId = data.NewConstr(0, a.ActionId.ToPlutusData())
}
scriptHash := data.NewConstr(1)
if len(a.Constitution.ScriptHash) > 0 {
scriptHash = data.NewConstr(
0,
data.NewByteString(a.Constitution.ScriptHash),
)
}
return data.NewConstr(5,
a.ActionId.ToPlutusData(),
actionId,
data.NewConstr(0,
a.Constitution.Anchor.ToPlutusData(),
data.NewByteString(a.Constitution.ScriptHash),
scriptHash,
),
)
}
Expand Down
39 changes: 6 additions & 33 deletions ledger/common/gov_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -262,23 +262,6 @@ func TestVotingProcedureToPlutusData(t *testing.T) {
}
}

func TestProposalProcedureToPlutusData(t *testing.T) {
addr := Address{}
action := &InfoGovAction{}

pp := &ProposalProcedure{
Deposit: 1000000,
RewardAccount: addr,
GovAction: GovActionWrapper{Action: action},
}

pd := pp.ToPlutusData()
constr, ok := pd.(*data.Constr)
assert.True(t, ok)
assert.Equal(t, uint(0), constr.Tag)
assert.Len(t, constr.Fields, 3)
}

func TestGovActionIdToPlutusData(t *testing.T) {
txId := [32]byte{1, 2, 3, 4}
govActionId := &GovActionId{
Expand All @@ -293,20 +276,6 @@ func TestGovActionIdToPlutusData(t *testing.T) {
assert.Len(t, constr.Fields, 2)
}

func TestParameterChangeGovActionToPlutusData(t *testing.T) {
action := &ParameterChangeGovAction{
ActionId: &GovActionId{},
ParamUpdate: []byte{1, 2, 3},
PolicyHash: []byte{4, 5, 6},
}

pd := action.ToPlutusData()
constr, ok := pd.(*data.Constr)
assert.True(t, ok)
assert.Equal(t, uint(0), constr.Tag)
assert.Len(t, constr.Fields, 3)
}

func TestHardForkInitiationGovActionToPlutusData(t *testing.T) {
action := &HardForkInitiationGovAction{
ActionId: &GovActionId{},
Expand Down Expand Up @@ -383,12 +352,16 @@ func TestUpdateCommitteeGovActionToPlutusData(t *testing.T) {
assert.True(t, ok)
assert.Equal(t, uint(4), constr.Tag)

innerConstr, ok := constr.Fields[3].(*data.Constr)
assert.True(t, ok)
assert.Equal(t, uint(0), innerConstr.Tag)

// Verify default values were used
num, ok := constr.Fields[3].(*data.Integer)
num, ok := innerConstr.Fields[0].(*data.Integer)
assert.True(t, ok)
assert.Equal(t, int64(0), num.Inner.Int64())

den, ok := constr.Fields[4].(*data.Integer)
den, ok := innerConstr.Fields[1].(*data.Integer)
assert.True(t, ok)
assert.Equal(t, int64(1), den.Inner.Int64())
})
Expand Down
30 changes: 15 additions & 15 deletions ledger/common/script/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -161,8 +161,7 @@ func (t TxInfoV3) ToPlutusData() data.PlutusData {
t.Data.ToPlutusData(),
data.NewByteString(t.Id.Bytes()),
t.Votes.ToPlutusData(),
// TODO: proposal procedures
toPlutusData([]any{}),
toPlutusData(t.ProposalProcedures),
t.CurrentTreasuryAmount.ToPlutusData(),
t.TreasuryDonation.ToPlutusData(),
)
Expand All @@ -188,6 +187,7 @@ func NewTxInfoV3FromTransaction(
inputs := sortInputs(tx.Inputs())
withdrawals := withdrawalsInfo(tx.Withdrawals())
votes := votingInfo(tx.VotingProcedures())
proposalProcedures := tx.ProposalProcedures()
redeemers := redeemersInfo(
tx.Witnesses(),
scriptPurposeBuilder(
Expand All @@ -196,8 +196,8 @@ func NewTxInfoV3FromTransaction(
*assetMint,
tx.Certificates(),
withdrawals,
// TODO: proposal procedures
votes,
proposalProcedures,
),
)
tmpData := dataInfo(tx.Witnesses())
Expand All @@ -207,18 +207,18 @@ func NewTxInfoV3FromTransaction(
sortInputs(tx.ReferenceInputs()),
resolvedInputs,
),
Outputs: collapseOutputs(tx.Produced()),
Fee: tx.Fee(),
Mint: *assetMint,
ValidRange: validityRange,
Certificates: tx.Certificates(),
Withdrawals: withdrawals,
Signatories: signatoriesInfo(tx.RequiredSigners()),
Redeemers: redeemers,
Data: tmpData,
Id: tx.Hash(),
Votes: votes,
// TODO: ProposalProcedures
Outputs: collapseOutputs(tx.Produced()),
Fee: tx.Fee(),
Mint: *assetMint,
ValidRange: validityRange,
Certificates: tx.Certificates(),
Withdrawals: withdrawals,
Signatories: signatoriesInfo(tx.RequiredSigners()),
Redeemers: redeemers,
Data: tmpData,
Id: tx.Hash(),
Votes: votes,
ProposalProcedures: proposalProcedures,
}
if amt := tx.CurrentTreasuryValue(); amt > 0 {
ret.CurrentTreasuryAmount.Value = amt
Expand Down
Loading
Loading