Skip to content

Commit

Permalink
Completed basic checks and fixed existing unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
HerbertJordan committed Dec 20, 2024
1 parent ba64fe4 commit afdec4a
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 19 deletions.
27 changes: 15 additions & 12 deletions opera/marshal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,28 +11,31 @@ import (
func TestUpdateRules(t *testing.T) {
require := require.New(t)

var exp Rules
exp.Epochs.MaxEpochGas = 99
base := MainNetRules()

got, err := UpdateRules(base, []byte(`{"Dag":{"MaxParents":5},"Economy":{"MinGasPrice":7},"Blocks":{"MaxBlockGas":2000000000}}`))
require.NoError(err)

exp := base.Copy()
exp.Dag.MaxParents = 5
exp.Economy.MinGasPrice = big.NewInt(7)
exp.Economy.MinBaseFee = big.NewInt(12)
exp.Blocks.MaxBlockGas = 1000
got, err := UpdateRules(exp, []byte(`{"Dag":{"MaxParents":5},"Economy":{"MinGasPrice":7},"Blocks":{"MaxBlockGas":2000000000}}`))
require.NoError(err)
require.Equal(exp.String(), got.String(), "mutate fields") // < this test checks nothing; todo: fix
exp.Blocks.MaxBlockGas = 2000000000

exp.Dag.MaxParents = 0
got, err = UpdateRules(exp, []byte(`{"Name":"xxx","NetworkID":1,"Dag":{"MaxParents":0}}`))
require.Equal(exp.String(), got.String(), "failed to update mutable fields")

got, err = UpdateRules(exp, []byte(`{"Name":"xxx","NetworkID":1}`))
require.NoError(err)
require.Equal(exp.String(), got.String(), "readonly fields")
require.Equal(exp.String(), got.String(), "should not be able to change readonly fields")

got, err = UpdateRules(exp, []byte(`{}`))
require.NoError(err)
require.Equal(exp.String(), got.String(), "empty diff")
require.Equal(exp.String(), got.String(), "empty diff changed the rules")

_, err = UpdateRules(exp, []byte(`}{`))
require.Error(err)
require.Error(err, "should fail on invalid json")

_, err = UpdateRules(exp, []byte(`{"Dag":{"MaxParents":1}}`))
require.Error(err, "should fail on invalid rules")
}

func TestMainNetRulesRLP(t *testing.T) {
Expand Down
6 changes: 6 additions & 0 deletions opera/rules.go
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,12 @@ func MainNetRules() Rules {
MaxBlockGas: MinimumMaxBlockGas,
MaxEmptyBlockSkipPeriod: inter.Timestamp(1 * time.Minute),
},
Upgrades: Upgrades{
Berlin: true,
London: true,
Llr: false,
Sonic: true,
},
}
}

Expand Down
51 changes: 44 additions & 7 deletions opera/validate.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,6 @@ import (
"github.com/Fantom-foundation/go-opera/inter"
)

var (
maxMinimumGasPrice = new(big.Int).SetUint64(1000 * 1e9) // 1000 Gwei
)

func validate(rules Rules) error {
return errors.Join(
validateDagRules(rules.Dag),
Expand All @@ -30,6 +26,10 @@ func validateDagRules(rules DagRules) error {
issues = append(issues, errors.New("Dag.MaxParents is too low"))
}

if rules.MaxFreeParents < 2 {
issues = append(issues, errors.New("Dag.MaxFreeParents is too low"))
}

if rules.MaxExtraData > 1<<20 { // 1 MB
issues = append(issues, errors.New("Dag.MaxExtraData is too high"))
}
Expand Down Expand Up @@ -90,6 +90,13 @@ func validateBlockRules(rules BlocksRules) error {
return errors.Join(issues...)
}

var (
// maxMinimumGasPrice is the maximum allowed minimum gas price. An upper limit is
// added to avoid a situation where the gas-free pricing is accidentally set to such
// a high value that another rule-change can no longer be afforded.
maxMinimumGasPrice = new(big.Int).SetUint64(1000 * 1e9) // 1000 Gwei
)

func validateEconomyRules(rules EconomyRules) error {
var issues []error

Expand All @@ -115,7 +122,7 @@ func validateEconomyRules(rules EconomyRules) error {
}
}

// TODO: check BlockMissedSlack
// There are deliberately no checks for the BlockMissedSlack. This can be set to any value.

issues = append(issues, validateGasRules(rules.Gas))
issues = append(issues, validateGasPowerRules("Economy.ShortGasPower", rules.ShortGasPower))
Expand All @@ -124,18 +131,48 @@ func validateEconomyRules(rules EconomyRules) error {
return errors.Join(issues...)
}

const (
// upperBoundForRuleChangeGasCosts is a safe over-approximation of the gas costs of a rule change.
upperBoundForRuleChangeGasCosts = 1_000_000 // < TODO: verify this number
)

func validateGasRules(rules GasRules) error {
var issues []error

// TODO: implement
if rules.MaxEventGas < upperBoundForRuleChangeGasCosts {
issues = append(issues, errors.New("Gas.MaxEventGas is too low"))
}

if rules.MaxEventGas-rules.EventGas < upperBoundForRuleChangeGasCosts {
issues = append(issues, errors.New("Gas.EventGas is too high"))
}

// Right now, we do not have a rule that would limit the ParentGas, or ExtraDataGas.

return errors.Join(issues...)
}

func validateGasPowerRules(prefix string, rules GasPowerRules) error {
// The main aim of those rule-checks is to prevent a situation where
// accidentally the gas-power is reduced to a level where no new rule
// change can be processed anymore.

var issues []error

// TODO: implement
if rules.AllocPerSec < 10*upperBoundForRuleChangeGasCosts {
issues = append(issues, errors.New(prefix+".AllocPerSec is too low"))
}

if rules.MaxAllocPeriod < inter.Timestamp(1*time.Second) {
issues = append(issues, errors.New(prefix+".MaxAllocPeriod is too low"))
}
if rules.MaxAllocPeriod > inter.Timestamp(1*time.Minute) {
issues = append(issues, errors.New(prefix+".MaxAllocPeriod is too high"))
}

if rules.StartupAllocPeriod < inter.Timestamp(1*time.Second) {
issues = append(issues, errors.New(prefix+".StartupAllocPeriod is too low"))
}

return errors.Join(issues...)
}
Expand Down

0 comments on commit afdec4a

Please sign in to comment.