From 2e9940b4fbcf84e267f0fa52bd9b21aa8e36905d Mon Sep 17 00:00:00 2001 From: Aurora Gaffney Date: Tue, 14 May 2024 14:24:08 -0500 Subject: [PATCH] feat: TX voting procedures attribute support This adds support for decoding and retrieving Conway voting procedures from a TX Fixes #343 --- ledger/allegra.go | 4 ++++ ledger/alonzo.go | 4 ++++ ledger/babbage.go | 4 ++++ ledger/byron.go | 5 +++++ ledger/conway.go | 57 +++++++++++++++++++++++++++++++++++++++++++---- ledger/mary.go | 4 ++++ ledger/shelley.go | 9 ++++++++ ledger/tx.go | 1 + 8 files changed, 84 insertions(+), 4 deletions(-) diff --git a/ledger/allegra.go b/ledger/allegra.go index ed445bfd..099413ec 100644 --- a/ledger/allegra.go +++ b/ledger/allegra.go @@ -178,6 +178,10 @@ func (t AllegraTransaction) Withdrawals() map[*Address]uint64 { return t.Body.Withdrawals() } +func (t AllegraTransaction) VotingProcedures() VotingProcedures { + return t.Body.VotingProcedures() +} + func (t AllegraTransaction) Metadata() *cbor.Value { return t.TxMetadata } diff --git a/ledger/alonzo.go b/ledger/alonzo.go index 57edbac9..5f067ad9 100644 --- a/ledger/alonzo.go +++ b/ledger/alonzo.go @@ -288,6 +288,10 @@ func (t AlonzoTransaction) Withdrawals() map[*Address]uint64 { return t.Body.Withdrawals() } +func (t AlonzoTransaction) VotingProcedures() VotingProcedures { + return t.Body.VotingProcedures() +} + func (t AlonzoTransaction) Metadata() *cbor.Value { return t.TxMetadata } diff --git a/ledger/babbage.go b/ledger/babbage.go index 9c6a64e2..70f6550a 100644 --- a/ledger/babbage.go +++ b/ledger/babbage.go @@ -464,6 +464,10 @@ func (t BabbageTransaction) Withdrawals() map[*Address]uint64 { return t.Body.Withdrawals() } +func (t BabbageTransaction) VotingProcedures() VotingProcedures { + return t.Body.VotingProcedures() +} + func (t BabbageTransaction) Metadata() *cbor.Value { return t.TxMetadata } diff --git a/ledger/byron.go b/ledger/byron.go index 5b7bb07f..56dba496 100644 --- a/ledger/byron.go +++ b/ledger/byron.go @@ -200,6 +200,11 @@ func (t *ByronTransaction) Withdrawals() map[*Address]uint64 { return nil } +func (t *ByronTransaction) VotingProcedures() VotingProcedures { + // No voting procedures in Byron + return nil +} + func (t *ByronTransaction) Metadata() *cbor.Value { return t.Attributes } diff --git a/ledger/conway.go b/ledger/conway.go index 3e88a5af..4866d338 100644 --- a/ledger/conway.go +++ b/ledger/conway.go @@ -121,16 +121,61 @@ func (h *ConwayBlockHeader) Era() Era { type ConwayTransactionBody struct { BabbageTransactionBody - VotingProcedures *cbor.Value `cbor:"19,keyasint,omitempty"` - ProposalProcedures *cbor.Value `cbor:"20,keyasint,omitempty"` - CurrentTreasuryValue int64 `cbor:"21,keyasint,omitempty"` - Donation uint64 `cbor:"22,keyasint,omitempty"` + TxVotingProcedures VotingProcedures `cbor:"19,keyasint,omitempty"` + ProposalProcedures *cbor.Value `cbor:"20,keyasint,omitempty"` + CurrentTreasuryValue int64 `cbor:"21,keyasint,omitempty"` + Donation uint64 `cbor:"22,keyasint,omitempty"` } func (b *ConwayTransactionBody) UnmarshalCBOR(cborData []byte) error { return b.UnmarshalCbor(cborData, b) } +func (b *ConwayTransactionBody) VotingProcedures() VotingProcedures { + return b.TxVotingProcedures +} + +// VotingProcedures is a convenience type to avoid needing to duplicate the full type definition everywhere +type VotingProcedures map[*Voter]map[*GovActionId]VotingProcedure + +const ( + VoterTypeConstitutionalCommitteeHotKeyHash uint8 = 0 + VoterTypeConstitutionalCommitteeHotScriptHash = 1 + VoterTypeDRepKeyHash = 2 + VoterTypeDRepScriptHash = 3 + VoterTypeStakingPoolKeyHash = 4 +) + +type Voter struct { + cbor.StructAsArray + Type uint8 + Hash [28]byte +} + +const ( + GovVoteNo uint8 = 0 + GovVoteYes = 1 + GovVoteAbstain = 2 +) + +type VotingProcedure struct { + cbor.StructAsArray + Vote uint8 + Anchor *GovAnchor +} + +type GovAnchor struct { + cbor.StructAsArray + Url string + DataHash [32]byte +} + +type GovActionId struct { + cbor.StructAsArray + TransactionId [32]byte + GovActionIdx uint32 +} + type ConwayTransaction struct { cbor.StructAsArray cbor.DecodeStoreCbor @@ -184,6 +229,10 @@ func (t ConwayTransaction) Withdrawals() map[*Address]uint64 { return t.Body.Withdrawals() } +func (t ConwayTransaction) VotingProcedures() VotingProcedures { + return t.Body.VotingProcedures() +} + func (t ConwayTransaction) Metadata() *cbor.Value { return t.TxMetadata } diff --git a/ledger/mary.go b/ledger/mary.go index 6f0d6617..6519534e 100644 --- a/ledger/mary.go +++ b/ledger/mary.go @@ -195,6 +195,10 @@ func (t MaryTransaction) Withdrawals() map[*Address]uint64 { return t.Body.Withdrawals() } +func (t MaryTransaction) VotingProcedures() VotingProcedures { + return t.Body.VotingProcedures() +} + func (t MaryTransaction) Metadata() *cbor.Value { return t.TxMetadata } diff --git a/ledger/shelley.go b/ledger/shelley.go index fcd82494..7a8e1beb 100644 --- a/ledger/shelley.go +++ b/ledger/shelley.go @@ -244,6 +244,11 @@ func (b *ShelleyTransactionBody) Withdrawals() map[*Address]uint64 { return b.TxWithdrawals } +func (t *ShelleyTransactionBody) VotingProcedures() VotingProcedures { + // No voting procedures in Shelley + return nil +} + func (b *ShelleyTransactionBody) Utxorpc() *utxorpc.Tx { var txi []*utxorpc.TxInput var txo []*utxorpc.TxOutput @@ -402,6 +407,10 @@ func (t ShelleyTransaction) Withdrawals() map[*Address]uint64 { return t.Body.Withdrawals() } +func (t ShelleyTransaction) VotingProcedures() VotingProcedures { + return t.Body.VotingProcedures() +} + func (t ShelleyTransaction) Metadata() *cbor.Value { return t.TxMetadata } diff --git a/ledger/tx.go b/ledger/tx.go index b8caf324..040dba8c 100644 --- a/ledger/tx.go +++ b/ledger/tx.go @@ -46,6 +46,7 @@ type TransactionBody interface { TotalCollateral() uint64 Certificates() []Certificate Withdrawals() map[*Address]uint64 + VotingProcedures() VotingProcedures Utxorpc() *utxorpc.Tx }