diff --git a/ledger/alonzo/genesis.go b/ledger/alonzo/genesis.go index f54c99c0..7acf569b 100644 --- a/ledger/alonzo/genesis.go +++ b/ledger/alonzo/genesis.go @@ -22,21 +22,20 @@ import ( ) type AlonzoGenesis struct { - LovelacePerUtxoWord uint64 `json:"lovelacePerUTxOWord"` - MaxValueSize uint - CollateralPercentage uint - MaxCollateralInputs uint - ExecutionPrices AlonzoGenesisExecutionPrices - MaxTxExUnits AlonzoGenesisExUnits - MaxBlockExUnits AlonzoGenesisExUnits - CostModels map[string]map[string]int + LovelacePerUtxoWord uint64 `json:"lovelacePerUTxOWord"` + MaxValueSize uint `json:"maxValueSize"` + CollateralPercentage uint `json:"collateralPercentage"` + MaxCollateralInputs uint `json:"maxCollateralInputs"` + ExecutionPrices AlonzoGenesisExecutionPrices `json:"executionPrices"` + MaxTxExUnits AlonzoGenesisExUnits `json:"maxTxExUnits"` + MaxBlockExUnits AlonzoGenesisExUnits `json:"maxBlockExUnits"` + CostModels map[string]map[string]int `json:"costModels"` } func NewAlonzoGenesisFromReader(r io.Reader) (AlonzoGenesis, error) { var ret AlonzoGenesis dec := json.NewDecoder(r) dec.DisallowUnknownFields() - //nolint:musttag if err := dec.Decode(&ret); err != nil { return ret, err } diff --git a/ledger/alonzo/genesis_test.go b/ledger/alonzo/genesis_test.go index 7069ba54..ce69cab4 100644 --- a/ledger/alonzo/genesis_test.go +++ b/ledger/alonzo/genesis_test.go @@ -430,3 +430,62 @@ func TestGenesisFromJson(t *testing.T) { ) } } + +func TestNewAlonzoGenesisFromReader(t *testing.T) { + jsonData := `{ + "lovelacePerUTxOWord": 34482, + "maxValueSize": 5000, + "collateralPercentage": 150, + "maxCollateralInputs": 3, + "executionPrices": { + "prSteps": { "numerator": 721, "denominator": 10000 }, + "prMem": { "numerator": 577, "denominator": 10000 } + }, + "maxTxExUnits": { "exUnitsMem": 1000000, "exUnitsSteps": 10000000 }, + "maxBlockExUnits": { "exUnitsMem": 50000000, "exUnitsSteps": 40000000000 }, + "costModels": { + "PlutusV1": { + "addInteger-cpu-arguments-intercept": 205665, + "addInteger-cpu-arguments-slope": 812 + } + } + }` + + reader := strings.NewReader(jsonData) + result, err := alonzo.NewAlonzoGenesisFromReader(reader) + if err != nil { + t.Errorf("Failed to decode JSON: %v", err) + } + + if result.LovelacePerUtxoWord != 34482 { + t.Errorf("Expected LovelacePerUtxoWord 34482, got %d", result.LovelacePerUtxoWord) + } else { + t.Logf("LovelacePerUtxoWord is correct: %d", result.LovelacePerUtxoWord) + } + + if result.ExecutionPrices.Steps.Rat.Cmp(big.NewRat(721, 10000)) != 0 { + t.Errorf("Unexpected prSteps: got %v, expected 721/10000", result.ExecutionPrices.Steps.Rat) + } else { + t.Logf("prSteps is correct: %v", result.ExecutionPrices.Steps.Rat) + } + + if result.ExecutionPrices.Mem.Rat.Cmp(big.NewRat(577, 10000)) != 0 { + t.Errorf("Unexpected prMem: got %v, expected 577/10000", result.ExecutionPrices.Mem.Rat) + } else { + t.Logf("prMem is correct: %v", result.ExecutionPrices.Mem.Rat) + } + + expectedCostModels := map[string]map[string]int{ + "PlutusV1": { + "addInteger-cpu-arguments-intercept": 205665, + "addInteger-cpu-arguments-slope": 812, + }, + } + if !reflect.DeepEqual(result.CostModels, expectedCostModels) { + t.Errorf("Unexpected CostModels:\nGot: %v\nExpected: %v", result.CostModels, expectedCostModels) + } else { + t.Logf("CostModels are correct") + } + + t.Logf("AlonzoGenesis JSON decoding test completed successfully.") +} diff --git a/ledger/byron/genesis.go b/ledger/byron/genesis.go index bec25b30..49ec7cc8 100644 --- a/ledger/byron/genesis.go +++ b/ledger/byron/genesis.go @@ -27,15 +27,15 @@ import ( ) type ByronGenesis struct { - AvvmDistr map[string]string - BlockVersionData ByronGenesisBlockVersionData - FtsSeed string - ProtocolConsts ByronGenesisProtocolConsts - StartTime int - BootStakeholders map[string]int - HeavyDelegation map[string]ByronGenesisHeavyDelegation - NonAvvmBalances map[string]string - VssCerts map[string]ByronGenesisVssCert + AvvmDistr map[string]string `json:"avvmDistr"` + BlockVersionData ByronGenesisBlockVersionData `json:"blockVersionData"` + FtsSeed string `json:"ftsSeed"` + ProtocolConsts ByronGenesisProtocolConsts `json:"protocolConsts"` + StartTime int `json:"startTime"` + BootStakeholders map[string]int `json:"bootStakeholders"` + HeavyDelegation map[string]ByronGenesisHeavyDelegation `json:"heavyDelegation"` + NonAvvmBalances map[string]string `json:"nonAvvmBalances"` + VssCerts map[string]ByronGenesisVssCert `json:"vssCerts"` } type ByronGenesisBlockVersionData struct { @@ -180,7 +180,6 @@ func NewByronGenesisFromReader(r io.Reader) (ByronGenesis, error) { var ret ByronGenesis dec := json.NewDecoder(r) dec.DisallowUnknownFields() - //nolint:musttag if err := dec.Decode(&ret); err != nil { return ret, err } diff --git a/ledger/byron/genesis_test.go b/ledger/byron/genesis_test.go index 3d2fc1d9..2bf12a04 100644 --- a/ledger/byron/genesis_test.go +++ b/ledger/byron/genesis_test.go @@ -356,3 +356,76 @@ func TestGenesisAvvmUtxos(t *testing.T) { ) } } + +func TestNewByronGenesisFromReader(t *testing.T) { + jsonData := `{ + "avvmDistr": { "addr1": "1000" }, + "blockVersionData": { + "heavyDelThd": "1", + "maxBlockSize": "2", + "maxHeaderSize": "3", + "maxProposalSize": "4", + "maxTxSize": "5", + "mpcThd": "6", + "scriptVersion": 1, + "slotDuration": "7", + "softforkRule": { + "initThd": "8", + "minThd": "9", + "thdDecrement": "10" + }, + "txFeePolicy": { + "multiplier": "11", + "summand": "12" + }, + "unlockStakeEpoch": "13", + "updateImplicit": "14", + "updateProposalThd": "15", + "updateVoteThd": "16" + }, + "ftsSeed": "seed", + "protocolConsts": { + "k": 1, + "protocolMagic": 42, + "vssMinTtl": 2, + "vssMaxTtl": 10 + }, + "startTime": 100000, + "bootStakeholders": { "stakeholder1": 1 }, + "heavyDelegation": { + "key1": { + "cert": "cert-val", + "delegatePk": "delegate-pk", + "issuerPk": "issuer-pk", + "omega": 5 + } + }, + "nonAvvmBalances": { "addr2": "2000" }, + "vssCerts": { + "cert1": { + "expiryEpoch": 5, + "signature": "sig", + "signingKey": "sign-key", + "vssKey": "vss-key" + } + } + }` + + expected := byron.ByronGenesis{} + err := json.Unmarshal([]byte(jsonData), &expected) + if err != nil { + t.Errorf("Failed to unmarshal expected: %v", err) + } + + reader := strings.NewReader(jsonData) + result, err := byron.NewByronGenesisFromReader(reader) + if err != nil { + t.Errorf("Failed to decode: %v", err) + } + + if !reflect.DeepEqual(result, expected) { + t.Errorf("ByronGenesis struct does not match expected.\nGot: %#v\nExpected: %#v", result, expected) + } else { + t.Logf("ByronGenesis decoded correctly") + } +} diff --git a/ledger/conway/genesis.go b/ledger/conway/genesis.go index fff7b610..f71ecceb 100644 --- a/ledger/conway/genesis.go +++ b/ledger/conway/genesis.go @@ -23,18 +23,18 @@ import ( ) type ConwayGenesis struct { - PoolVotingThresholds ConwayGenesisPoolVotingThresholds - DRepVotingThresholds ConwayGenesisDRepVotingThresholds - MinCommitteeSize uint `json:"committeeMinSize"` - CommitteeTermLimit uint64 `json:"committeeMaxTermLength"` - GovActionValidityPeriod uint64 `json:"govActionLifetime"` - GovActionDeposit uint64 - DRepDeposit uint64 `json:"dRepDeposit"` - DRepInactivityPeriod uint64 `json:"dRepActivity"` - MinFeeRefScriptCostPerByte *common.GenesisRat - PlutusV3CostModel []int64 `json:"plutusV3CostModel"` - Constitution ConwayGenesisConstitution - Committee ConwayGenesisCommittee + PoolVotingThresholds ConwayGenesisPoolVotingThresholds `json:"poolVotingThresholds"` + DRepVotingThresholds ConwayGenesisDRepVotingThresholds `json:"dRepVotingThresholds"` + MinCommitteeSize uint `json:"committeeMinSize"` + CommitteeTermLimit uint64 `json:"committeeMaxTermLength"` + GovActionValidityPeriod uint64 `json:"govActionLifetime"` + GovActionDeposit uint64 `json:"govActionDeposit"` + DRepDeposit uint64 `json:"dRepDeposit"` + DRepInactivityPeriod uint64 `json:"dRepActivity"` + MinFeeRefScriptCostPerByte *common.GenesisRat `json:"minFeeRefScriptCostPerByte"` + PlutusV3CostModel []int64 `json:"plutusV3CostModel"` + Constitution ConwayGenesisConstitution `json:"constitution"` + Committee ConwayGenesisCommittee `json:"committee"` } type ConwayGenesisPoolVotingThresholds struct { @@ -77,7 +77,6 @@ func NewConwayGenesisFromReader(r io.Reader) (ConwayGenesis, error) { var ret ConwayGenesis dec := json.NewDecoder(r) dec.DisallowUnknownFields() - //nolint:musttag if err := dec.Decode(&ret); err != nil { return ret, err } diff --git a/ledger/conway/genesis_test.go b/ledger/conway/genesis_test.go index 79021509..6741808e 100644 --- a/ledger/conway/genesis_test.go +++ b/ledger/conway/genesis_test.go @@ -15,6 +15,7 @@ package conway_test import ( + "encoding/json" "math/big" "reflect" "strings" @@ -401,3 +402,64 @@ func TestGenesisFromJson(t *testing.T) { ) } } + +func TestNewConwayGenesisFromReader(t *testing.T) { + jsonData := `{ + "poolVotingThresholds": { + "committeeNormal": null, + "committeeNoConfidence": null, + "hardForkInitiation": null, + "motionNoConfidence": null, + "ppSecurityGroup": null + }, + "dRepVotingThresholds": { + "motionNoConfidence": null, + "committeeNormal": null, + "committeeNoConfidence": null, + "updateToConstitution": null, + "hardForkInitiation": null, + "ppNetworkGroup": null, + "ppEconomicGroup": null, + "ppTechnicalGroup": null, + "ppGovGroup": null, + "treasuryWithdrawal": null + }, + "committeeMinSize": 5, + "committeeMaxTermLength": 365, + "govActionLifetime": 90, + "govActionDeposit": 1000, + "dRepDeposit": 200, + "dRepActivity": 60, + "minFeeRefScriptCostPerByte": null, + "plutusV3CostModel": [1, 2, 3], + "constitution": { + "anchor": { + "dataHash": "abc123", + "url": "https://example.com" + }, + "script": "example-script" + }, + "committee": { + "members": { "key1": 1 }, + "threshold": { "key1": 2 } + } + }` + + expected := conway.ConwayGenesis{} + err := json.Unmarshal([]byte(jsonData), &expected) + if err != nil { + t.Errorf("Failed to unmarshal expected JSON: %v", err) + } + + reader := strings.NewReader(jsonData) + actual, err := conway.NewConwayGenesisFromReader(reader) + if err != nil { + t.Errorf("Failed to decode JSON via NewConwayGenesisFromReader: %v", err) + } + + if !reflect.DeepEqual(expected, actual) { + t.Errorf("Mismatch between expected and actual structs\nExpected: %#v\nActual: %#v", expected, actual) + } else { + t.Logf("ConwayGenesis decoded correctly and matches expected structure") + } +} diff --git a/ledger/shelley/genesis.go b/ledger/shelley/genesis.go index 991acdb1..0fb2e7a5 100644 --- a/ledger/shelley/genesis.go +++ b/ledger/shelley/genesis.go @@ -158,7 +158,6 @@ func NewShelleyGenesisFromReader(r io.Reader) (ShelleyGenesis, error) { var ret ShelleyGenesis dec := json.NewDecoder(r) dec.DisallowUnknownFields() - //nolint:musttag if err := dec.Decode(&ret); err != nil { return ret, err }