Skip to content

feat: changes to support cost models while updating Alonzo protocols through genesis config #984

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 10 commits into
base: main
Choose a base branch
from

Conversation

jkawan
Copy link

@jkawan jkawan commented Apr 14, 2025

  1. Changes added to support cost models when updating Alonzo protocol params from genesis config - mapped string keys to numeric indexes
  2. Changes to support both array and map from genesis files
  3. Added unit tests for the changes

Closes #852
Closes #963

@jkawan jkawan requested a review from a team as a code owner April 14, 2025 22:28
Copy link
Contributor

@agaffney agaffney left a comment

Choose a reason for hiding this comment

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

While this approach will technically work for decoding the Alonzo genesis in most networks, we'll want to be more explicit with the mapping of these keys to numeric index. This will allow us to convert back and forth between the formats, as well as do things like validate the inputs. Each of the 3 Plutus versions will have their own mapping.

We also need to be able to support the simple list format as seen in the devnet genesis config:

https://github.com/blinklabs-io/docker-cardano-configs/blob/main/config/devnet/alonzo-genesis.json

for lang, model := range genesis.CostModels {
var langKey uint
switch lang {
case "plutus:v1":
Copy link
Contributor

Choose a reason for hiding this comment

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

This is PlutusV1 in the JSON

switch lang {
case "plutus:v1":
langKey = 0
case "plutus:v2":
Copy link
Contributor

Choose a reason for hiding this comment

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

This is PlutusV2 in the JSON

langKey = 0
case "plutus:v2":
langKey = 1
default:
Copy link
Contributor

Choose a reason for hiding this comment

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

It's also possible to have a PlutusV3

@wolf31o2
Copy link
Member

We also need to be able to support the simple list format as seen in the devnet genesis config:

We have a separate issue for that one.

@@ -44,7 +60,7 @@ type AlonzoProtocolParameters struct {
MinUtxoValue uint
MinPoolCost uint64
AdaPerUtxoByte uint64
CostModels map[uint][]int64
CostModels map[PlutusVersion]*CostModel
Copy link
Contributor

Choose a reason for hiding this comment

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

This is (probably) going to break CBOR decoding of Alonzo protocol params. The previous struct field definition matches the structure of the CBOR data.

ProtocolMinor: prevPParams.ProtocolMinor,
MinUtxoValue: prevPParams.MinUtxoValue,
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Why did you remove this function? We use this in dingo

Copy link
Author

Choose a reason for hiding this comment

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

Apologies, I removed this function unintentionally while resolving the conflicts. fixing it

case "plutus:v2", "plutusv2":
return PlutusV2, true
case "plutus:v3", "plutusv3":
return PlutusV3, true
Copy link
Contributor

Choose a reason for hiding this comment

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

Where are any of these forms used?

Copy link
Author

Choose a reason for hiding this comment

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

fixing the forms

}
intVal = int64(floatVal)
}
versionMap[k] = int(intVal)
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we encounter all 3 of these types when parsing example Alonzo genesis files, or is this just covering our bases?

@@ -29,7 +30,7 @@ type AlonzoGenesis struct {
ExecutionPrices AlonzoGenesisExecutionPrices `json:"executionPrices"`
MaxTxExUnits AlonzoGenesisExUnits `json:"maxTxExUnits"`
MaxBlockExUnits AlonzoGenesisExUnits `json:"maxBlockExUnits"`
CostModels map[string]map[string]int `json:"costModels"`
CostModels map[string]interface{} `json:"costModels"`
Copy link
Contributor

Choose a reason for hiding this comment

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

This field type is going to force us to do something like foo.CostModels.(map[string]int)["foo"] every time that we access something from it, which isn't ideal. What we probably want is a separate CostModel type with a custom UnmarshalJSON() function that works similarly to NormalizeCostModels() below.

if genesis.ExecutionPrices.Mem != nil &&
genesis.ExecutionPrices.Steps != nil {

if genesis.ExecutionPrices.Mem != nil && genesis.ExecutionPrices.Steps != nil {
Copy link
Contributor

Choose a reason for hiding this comment

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

This is going to get split back to 2 lines the next time that we run golines on this repo

if _, err := fmt.Sscanf(paramName, "param%d", &index); err == nil && index > maxIndex {
maxIndex = index
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

This seems to be expecting a structure like this, but I'm not seeing where that would come from outside of the tests. It seems that it would be easier to use []int64 or similar.

{ "param0": 123, "param1": 234, "param2": 345 }

for i, val := range v {
if intVal, ok := val.(float64); ok {
values[i] = int64(intVal)
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Will this only ever contain float64 values? It looks like anything else would be ignored

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
3 participants