Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
53 changes: 53 additions & 0 deletions ledger/common/gov.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"fmt"

"github.com/blinklabs-io/gouroboros/cbor"
"github.com/blinklabs-io/plutigo/pkg/data"
)

// VotingProcedures is a convenience type to avoid needing to duplicate the full type definition everywhere
Expand All @@ -37,18 +38,70 @@ type Voter struct {
Hash [28]byte
}

func (v Voter) ToPlutusData() data.PlutusData {
switch v.Type {
case VoterTypeConstitutionalCommitteeHotScriptHash:
cred := &Credential{
CredType: CredentialTypeScriptHash,
Credential: NewBlake2b224(v.Hash[:]),
}
return data.NewConstr(0, cred.ToPlutusData())
case VoterTypeConstitutionalCommitteeHotKeyHash:
cred := &Credential{
CredType: CredentialTypeAddrKeyHash,
Credential: NewBlake2b224(v.Hash[:]),
}
return data.NewConstr(0, cred.ToPlutusData())
case VoterTypeDRepScriptHash:
cred := &Credential{
CredType: CredentialTypeScriptHash,
Credential: NewBlake2b224(v.Hash[:]),
}
return data.NewConstr(1, cred.ToPlutusData())
case VoterTypeDRepKeyHash:
cred := &Credential{
CredType: CredentialTypeAddrKeyHash,
Credential: NewBlake2b224(v.Hash[:]),
}
return data.NewConstr(1, cred.ToPlutusData())
case VoterTypeStakingPoolKeyHash:
return data.NewConstr(2, data.NewByteString(v.Hash[:]))
default:
return data.NewConstr(0)
Copy link
Contributor

Choose a reason for hiding this comment

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

return nil

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Made the changes and please review it.

}
}

const (
GovVoteNo uint8 = 0
GovVoteYes uint8 = 1
GovVoteAbstain uint8 = 2
)

type Vote uint8

func (v Vote) ToPlutusData() data.PlutusData {
switch v {
case Vote(GovVoteNo):
return data.NewConstr(0)
case Vote(GovVoteYes):
return data.NewConstr(1)
case Vote(GovVoteAbstain):
return data.NewConstr(2)
default:
return data.NewConstr(0)
Copy link
Contributor

Choose a reason for hiding this comment

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

This should return nil if we don't know the proper representation

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Made the changes and please review it.

}
}

type VotingProcedure struct {
cbor.StructAsArray
Vote uint8
Anchor *GovAnchor
}

func (vp VotingProcedure) ToPlutusData() data.PlutusData {
return Vote(vp.Vote).ToPlutusData()
}

type GovAnchor struct {
cbor.StructAsArray
Url string
Expand Down
179 changes: 179 additions & 0 deletions ledger/common/gov_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
// Copyright 2024 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 common

import (
"reflect"
"testing"

"github.com/blinklabs-io/plutigo/pkg/data"
)

// Ttests the ToPlutusData method for Voter types
func TestVoterToPlutusData(t *testing.T) {
// Use the same hash value for all tests to avoid confusion
testHash := [28]byte{0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11}
testHashBytes := []byte{0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11}

testCases := []struct {
name string
voter Voter
expectedData data.PlutusData
}{
{
name: "ConstitutionalCommitteeHotScriptHash",
voter: Voter{
Type: VoterTypeConstitutionalCommitteeHotScriptHash,
Hash: testHash,
},
expectedData: data.NewConstr(0, data.NewConstr(1, data.NewByteString(testHashBytes))),
},
{
name: "ConstitutionalCommitteeHotKeyHash",
voter: Voter{
Type: VoterTypeConstitutionalCommitteeHotKeyHash,
Hash: testHash,
},
expectedData: data.NewConstr(0, data.NewConstr(0, data.NewByteString(testHashBytes))),
},
{
name: "DRepScriptHash",
voter: Voter{
Type: VoterTypeDRepScriptHash,
Hash: testHash,
},
expectedData: data.NewConstr(1, data.NewConstr(1, data.NewByteString(testHashBytes))),
},
{
name: "DRepKeyHash",
voter: Voter{
Type: VoterTypeDRepKeyHash,
Hash: testHash,
},
expectedData: data.NewConstr(1, data.NewConstr(0, data.NewByteString(testHashBytes))),
},
{
name: "StakingPoolKeyHash",
voter: Voter{
Type: VoterTypeStakingPoolKeyHash,
Hash: testHash,
},
expectedData: data.NewConstr(2, data.NewByteString(testHashBytes)),
},
{
name: "UnknownType",
voter: Voter{
Type: 255, // Unknown type
Hash: [28]byte{},
},
expectedData: data.NewConstr(0),
},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
result := tc.voter.ToPlutusData()
if !reflect.DeepEqual(result, tc.expectedData) {
t.Errorf("ToPlutusData() = %#v, want %#v", result, tc.expectedData)
}
})
}
}

// Tests the ToPlutusData method for Vote types
func TestVoteToPlutusData(t *testing.T) {
testCases := []struct {
name string
vote Vote
expectedData data.PlutusData
}{
{
name: "No",
vote: Vote(GovVoteNo),
expectedData: data.NewConstr(0),
},
{
name: "Yes",
vote: Vote(GovVoteYes),
expectedData: data.NewConstr(1),
},
{
name: "Abstain",
vote: Vote(GovVoteAbstain),
expectedData: data.NewConstr(2),
},
{
name: "Unknown",
vote: Vote(255), // Unknown vote
expectedData: data.NewConstr(0),
},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
result := tc.vote.ToPlutusData()
if !reflect.DeepEqual(result, tc.expectedData) {
t.Errorf("ToPlutusData() = %#v, want %#v", result, tc.expectedData)
}
})
}
}

// Tests the ToPlutusData method for VotingProcedure types
func TestVotingProcedureToPlutusData(t *testing.T) {
testCases := []struct {
name string
procedure VotingProcedure
expectedData data.PlutusData
}{
{
name: "NoVote",
procedure: VotingProcedure{
Vote: GovVoteNo,
},
expectedData: data.NewConstr(0),
},
{
name: "YesVote",
procedure: VotingProcedure{
Vote: GovVoteYes,
},
expectedData: data.NewConstr(1),
},
{
name: "AbstainVote",
procedure: VotingProcedure{
Vote: GovVoteAbstain,
},
expectedData: data.NewConstr(2),
},
{
name: "UnknownVote",
procedure: VotingProcedure{
Vote: 255, // Unknown vote
},
expectedData: data.NewConstr(0),
},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
result := tc.procedure.ToPlutusData()
if !reflect.DeepEqual(result, tc.expectedData) {
t.Errorf("ToPlutusData() = %#v, want %#v", result, tc.expectedData)
}
})
}
}