-
Notifications
You must be signed in to change notification settings - Fork 20.2k
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
rpc: implement JSON marshaling of BlockNumber #23324
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I agree with the argument made in this PR, not sure if there are any consequences that we need to consider...?
for _, test := range tests { | ||
test := test | ||
t.Run(test.name, func(t *testing.T) { | ||
bnh := BlockNumberOrHashWithNumber(BlockNumber(test.number)) | ||
marshalled, err := json.Marshal(bnh) | ||
if err != nil { | ||
t.Fatal("cannot marshal:", err) | ||
} | ||
var unmarshalled BlockNumberOrHash | ||
err = json.Unmarshal(marshalled, &unmarshalled) | ||
if err != nil { | ||
t.Fatal("cannot unmarshal:", err) | ||
} | ||
if !reflect.DeepEqual(bnh, unmarshalled) { | ||
t.Fatalf("wrong result: expected %v, got %v", bnh, unmarshalled) | ||
} | ||
}) | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Might skip a layer of test nesting:
for _, test := range tests { | |
test := test | |
t.Run(test.name, func(t *testing.T) { | |
bnh := BlockNumberOrHashWithNumber(BlockNumber(test.number)) | |
marshalled, err := json.Marshal(bnh) | |
if err != nil { | |
t.Fatal("cannot marshal:", err) | |
} | |
var unmarshalled BlockNumberOrHash | |
err = json.Unmarshal(marshalled, &unmarshalled) | |
if err != nil { | |
t.Fatal("cannot unmarshal:", err) | |
} | |
if !reflect.DeepEqual(bnh, unmarshalled) { | |
t.Fatalf("wrong result: expected %v, got %v", bnh, unmarshalled) | |
} | |
}) | |
} | |
} | |
for _, test := range tests { | |
bnh := BlockNumberOrHashWithNumber(BlockNumber(test.number)) | |
marshalled, err := json.Marshal(bnh) | |
if err != nil { | |
t.Fatal("cannot marshal:", err) | |
} | |
var unmarshalled BlockNumberOrHash | |
if err = json.Unmarshal(marshalled, &unmarshalled); err != nil { | |
t.Fatal("cannot unmarshal:", err) | |
} | |
if !reflect.DeepEqual(bnh, unmarshalled) { | |
t.Fatalf("wrong result: expected %v, got %v", bnh, unmarshalled) | |
} | |
} | |
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
test.name would become unused
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are two pros of test nesting here:
- failure related to one dataset doesn't suppress checking of other datasets,
- in case of failure, the report clearly shows for which of data sets the code doesn't work correctly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
--- FAIL: TestBlockNumberOrHash_WithNumber_MarshalAndUnmarshal (0.00s)
--- FAIL: TestBlockNumberOrHash_WithNumber_MarshalAndUnmarshal/pending (0.00s)
types_test.go:148: cannot unmarshal: json: cannot unmarshal object into Go value of type string
--- FAIL: TestBlockNumberOrHash_WithNumber_MarshalAndUnmarshal/latest (0.00s)
types_test.go:148: cannot unmarshal: json: cannot unmarshal object into Go value of type string
Currently rpc.BlockNumber is marshalled to JSON as a numeric value, which is wrong because BlockNumber.UnmarshalJSON() wants it to either be hex-encoded or string "earliest"/"latest"/"pending". As a result, the call chain rpc.BlockNumberOrHashWithNumber(123) -> json.Marshal() -> json.Unmarshal() fails with error "cannot unmarshal object into Go value of type string".
Currently rpc.BlockNumber is marshalled to JSON as a numeric value, which is wrong because BlockNumber.UnmarshalJSON() wants it to either be hex-encoded or string "earliest"/"latest"/"pending". As a result, the call chain rpc.BlockNumberOrHashWithNumber(123) -> json.Marshal() -> json.Unmarshal() fails with error "cannot unmarshal object into Go value of type string".
Currently rpc.BlockNumber is marshalled to JSON as a numeric value
{"blockNumber":123}
which is wrong because BlockNumber.UnmarshalJSON() wants it either to be hex-encoded or to have a special value ("earliest"/"latest"/"pending"). As a result, the chain rpc.BlockNumberOrHashWithNumber(123) -> json.Marshal() -> json.Unmarshal() fails with an error "cannot unmarshal object into Go value of type string".The PR fixes the issue by adding BlockNumber.MarshalText() method which outputs either a hex-encoded number or a special string depending on the given block number.