Skip to content

Commit

Permalink
Add hint and refund validation
Browse files Browse the repository at this point in the history
  • Loading branch information
george-dorin committed Dec 5, 2024
1 parent 129c734 commit b603fd7
Show file tree
Hide file tree
Showing 2 changed files with 168 additions and 1 deletion.
93 changes: 92 additions & 1 deletion core/services/job/job_orm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2070,7 +2070,8 @@ func TestORM_CreateJob_OCR2_With_DualTransmission(t *testing.T) {
require.ErrorContains(t, jobORM.CreateJob(ctx, &jb), "invalid transmitter address in dual transmission config")

dtTransmitterAddress := cltest.MustGenerateRandomKey(t)
completeDualTransmissionSpec := fmt.Sprintf(`

metaNotSliceDualTransmissionSpec := fmt.Sprintf(`
enableDualTransmission=true
[relayConfig.dualTransmission]
contractAddress = '0x613a38AC1659769640aaE063C651F48E0250454C'
Expand All @@ -2081,6 +2082,96 @@ func TestORM_CreateJob_OCR2_With_DualTransmission(t *testing.T) {
`,
dtTransmitterAddress.Address.String())

jb, err = ocr2validate.ValidatedOracleSpecToml(testutils.Context(t), config.OCR2(), config.Insecure(), baseJobSpec+metaNotSliceDualTransmissionSpec, nil)
require.NoError(t, err)
require.ErrorContains(t, jobORM.CreateJob(ctx, &jb), "dual transmission meta value key1 is not a slice")

hintNotValidDualTransmissionSpec := fmt.Sprintf(`
enableDualTransmission=true
[relayConfig.dualTransmission]
contractAddress = '0x613a38AC1659769640aaE063C651F48E0250454C'
transmitterAddress = '%s'
[relayConfig.dualTransmission.meta]
hint = ['some-invalid-hint']
key2 = ['val2','val3']
`,
dtTransmitterAddress.Address.String())

jb, err = ocr2validate.ValidatedOracleSpecToml(testutils.Context(t), config.OCR2(), config.Insecure(), baseJobSpec+hintNotValidDualTransmissionSpec, nil)
require.NoError(t, err)
require.ErrorContains(t, jobORM.CreateJob(ctx, &jb), "dual transmission meta.hint value some-invalid-hint should be one of the following [contract_address function_selector logs calldata default_logs]")

invalidRefundFormatDualTransmissionSpec := fmt.Sprintf(`
enableDualTransmission=true
[relayConfig.dualTransmission]
contractAddress = '0x613a38AC1659769640aaE063C651F48E0250454C'
transmitterAddress = '%s'
[relayConfig.dualTransmission.meta]
hint = ['calldata','logs']
refund = ['0x00']
`,
dtTransmitterAddress.Address.String())

jb, err = ocr2validate.ValidatedOracleSpecToml(testutils.Context(t), config.OCR2(), config.Insecure(), baseJobSpec+invalidRefundFormatDualTransmissionSpec, nil)
require.NoError(t, err)
require.ErrorContains(t, jobORM.CreateJob(ctx, &jb), "invalid dual transmission refund, format should be <ADDRESS>:<PERCENT>")

invalidRefundAddressFormatDualTransmissionSpec := fmt.Sprintf(`
enableDualTransmission=true
[relayConfig.dualTransmission]
contractAddress = '0x613a38AC1659769640aaE063C651F48E0250454C'
transmitterAddress = '%s'
[relayConfig.dualTransmission.meta]
hint = ['calldata','logs']
refund = ['0x000:50']
`,
dtTransmitterAddress.Address.String())

jb, err = ocr2validate.ValidatedOracleSpecToml(testutils.Context(t), config.OCR2(), config.Insecure(), baseJobSpec+invalidRefundAddressFormatDualTransmissionSpec, nil)
require.NoError(t, err)
require.ErrorContains(t, jobORM.CreateJob(ctx, &jb), "invalid dual transmission refund address, 0x000 is not a valid address")

invalidRefundPercentFormatDualTransmissionSpec := fmt.Sprintf(`
enableDualTransmission=true
[relayConfig.dualTransmission]
contractAddress = '0x613a38AC1659769640aaE063C651F48E0250454C'
transmitterAddress = '%s'
[relayConfig.dualTransmission.meta]
hint = ['calldata','logs']
refund = ['0x0000000000000000000000000000000000000000:A']
`,
dtTransmitterAddress.Address.String())

jb, err = ocr2validate.ValidatedOracleSpecToml(testutils.Context(t), config.OCR2(), config.Insecure(), baseJobSpec+invalidRefundPercentFormatDualTransmissionSpec, nil)
require.NoError(t, err)
require.ErrorContains(t, jobORM.CreateJob(ctx, &jb), "invalid dual transmission refund percent, A is not a number")

invalidRefundPercentTotalFormatDualTransmissionSpec := fmt.Sprintf(`
enableDualTransmission=true
[relayConfig.dualTransmission]
contractAddress = '0x613a38AC1659769640aaE063C651F48E0250454C'
transmitterAddress = '%s'
[relayConfig.dualTransmission.meta]
hint = ['calldata','logs']
refund = ['0x0000000000000000000000000000000000000000:50','0x0000000000000000000000000000000000000001:50']
`,
dtTransmitterAddress.Address.String())

jb, err = ocr2validate.ValidatedOracleSpecToml(testutils.Context(t), config.OCR2(), config.Insecure(), baseJobSpec+invalidRefundPercentTotalFormatDualTransmissionSpec, nil)
require.NoError(t, err)
require.ErrorContains(t, jobORM.CreateJob(ctx, &jb), "invalid dual transmission refund percentages, total sum of percentages must be less than 100")

completeDualTransmissionSpec := fmt.Sprintf(`
enableDualTransmission=true
[relayConfig.dualTransmission]
contractAddress = '0x613a38AC1659769640aaE063C651F48E0250454C'
transmitterAddress = '%s'
[relayConfig.dualTransmission.meta]
key1 = ['val1']
key2 = ['val2','val3']
`,
dtTransmitterAddress.Address.String())

jb, err = ocr2validate.ValidatedOracleSpecToml(testutils.Context(t), config.OCR2(), config.Insecure(), baseJobSpec+completeDualTransmissionSpec, nil)
require.NoError(t, err)

Expand Down
76 changes: 76 additions & 0 deletions core/services/job/orm.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import (
"fmt"
"reflect"
"slices"
"strconv"
"strings"
"time"

"github.com/ethereum/go-ethereum/common"
Expand Down Expand Up @@ -324,9 +326,19 @@ func (o *orm) CreateJob(ctx context.Context, jb *Job) error {
return errors.New("invalid transmitter address in dual transmission config")
}

rawMeta, ok := dualTransmissionConfig["meta"].(map[string]interface{})
if !ok {
return errors.New("invalid dual transmission meta")
}

if err = validateDualTransmissionMeta(rawMeta); err != nil {
return err
}

if err = validateKeyStoreMatchForRelay(ctx, jb.OCR2OracleSpec.Relay, tx.keyStore, dtTransmitterAddress); err != nil {
return errors.Wrap(err, "unknown dual transmission transmitterAddress")
}

}

specID, err := tx.insertOCR2OracleSpec(ctx, jb.OCR2OracleSpec)
Expand Down Expand Up @@ -1643,3 +1655,67 @@ func (r legacyGasStationServerSpecRow) toLegacyGasStationServerSpec() *LegacyGas
func (o *orm) loadJobSpecErrors(ctx context.Context, jb *Job) error {
return errors.Wrapf(o.ds.SelectContext(ctx, &jb.JobSpecErrors, `SELECT * FROM job_spec_errors WHERE job_id = $1`, jb.ID), "failed to load job spec errors for job %d", jb.ID)
}

func validateDualTransmissionHint(vals []interface{}) error {
accepted := []string{"contract_address", "function_selector", "logs", "calldata", "default_logs"}
for _, v := range vals {
valString, ok := v.(string)
if !ok {
return errors.Errorf("dual transmission meta value %v is not a string", v)
}
if !slices.Contains(accepted, valString) {
return errors.Errorf("dual transmission meta.hint value %s should be one of the following %s", valString, accepted)
}
}
return nil
}

func validateDualTransmissionRefund(vals []interface{}) error {
totalRefund := 0
for _, v := range vals {
valString, ok := v.(string)
if !ok {
return errors.Errorf("dual transmission meta value %v is not a string", v)
}

s := strings.Split(valString, ":")
if len(s) != 2 {
return errors.New("invalid dual transmission refund, format should be <ADDRESS>:<PERCENT>")
}
if !common.IsHexAddress(s[0]) {
return errors.Errorf("invalid dual transmission refund address, %s is not a valid address", s[0])
}
percent, err := strconv.Atoi(s[1])
if err != nil {
return errors.Errorf("invalid dual transmission refund percent, %s is not a number", s[1])
}
totalRefund += percent
}

if totalRefund >= 100 {
return errors.New("invalid dual transmission refund percentages, total sum of percentages must be less than 100")
}
return nil
}

func validateDualTransmissionMeta(meta map[string]interface{}) error {
for k, v := range meta {
metaFieldValues, ok := v.([]interface{})
if !ok {
return errors.Errorf("dual transmission meta value %s is not a slice", k)
}
if k == "hint" {
if err := validateDualTransmissionHint(metaFieldValues); err != nil {
return err
}
}

if k == "refund" {
if err := validateDualTransmissionRefund(metaFieldValues); err != nil {
return err
}
}
}

return nil
}

0 comments on commit b603fd7

Please sign in to comment.