Skip to content

Commit

Permalink
Attempt to fix json parsing trouble
Browse files Browse the repository at this point in the history
  • Loading branch information
p-offtermatt committed Sep 8, 2023
1 parent 0f6537c commit 91c97aa
Show file tree
Hide file tree
Showing 12 changed files with 98 additions and 2,017 deletions.
5 changes: 5 additions & 0 deletions tests/e2e/json_marshal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@ func TestProposalUnmarshal(t *testing.T) {
Status: "PROPOSAL_STATUS_PASSED",
}

type ProposalAndType struct {
RawProposal json.RawMessage
Type string
}

propAndType := &ProposalAndType{}
err := json.Unmarshal([]byte(proposalAndTypeString), propAndType)
if err != nil {
Expand Down
5 changes: 1 addition & 4 deletions tests/e2e/json_parser.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package main

import (
"bytes"
"encoding/json"
"os"
"path/filepath"
Expand All @@ -25,9 +24,7 @@ func (parser JSONParser) ReadTraceFromFile(path string) ([]Step, error) {
// Unmarshal the JSON into a slice of Step structs
var steps []Step

decoder := json.NewDecoder(bytes.NewReader(jsonData))
decoder.DisallowUnknownFields() // To avoid silent errors. Will cause an error if the JSON contains unknown fields
err = decoder.Decode(&steps)
err = json.Unmarshal(jsonData, &steps)
if err != nil {
return nil, err
}
Expand Down
152 changes: 83 additions & 69 deletions tests/e2e/json_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,18 @@ import (
"encoding/json"
"fmt"
"reflect"

"github.com/mitchellh/mapstructure"
)

// MarshalJSON marshals a step into JSON while including the type of the action.
func (step Step) MarshalJSON() ([]byte, error) {
actionType := reflect.TypeOf(step.Action).String()
actionType := reflect.TypeOf(step.Action)

result := struct {
ActionType string
Action interface{}
State State
}{
ActionType: actionType,
ActionType: actionType.String(),
Action: step.Action,
State: step.State,
}
Expand Down Expand Up @@ -47,79 +45,80 @@ func (step *Step) UnmarshalJSON(data []byte) error {
}

// has to be manually kept in sync with the available action types.
var actionRegistry = map[string]interface{}{
"main.submitConsumerAdditionProposalAction": submitConsumerAdditionProposalAction{},
"main.StartChainAction": StartChainAction{},
"main.SendTokensAction": SendTokensAction{},
"main.submitTextProposalAction": submitTextProposalAction{},
"main.submitConsumerRemovalProposalAction": submitConsumerRemovalProposalAction{},
"main.submitEquivocationProposalAction": submitEquivocationProposalAction{},
"main.submitParamChangeLegacyProposalAction": submitParamChangeLegacyProposalAction{},
"main.voteGovProposalAction": voteGovProposalAction{},
"main.startConsumerChainAction": startConsumerChainAction{},
"main.AddChainToRelayerAction": addChainToRelayerAction{},
"main.addIbcConnectionAction": addIbcConnectionAction{},
"main.addIbcChannelAction": addIbcChannelAction{},
"main.transferChannelCompleteAction": transferChannelCompleteAction{},
"main.unjailValidatorAction": unjailValidatorAction{},
"main.assignConsumerPubKeyAction": assignConsumerPubKeyAction{},
"main.delegateTokensAction": delegateTokensAction{},
"main.relayPacketsAction": relayPacketsAction{},
"main.registerRepresentativeAction": registerRepresentativeAction{},
"main.relayRewardPacketsToProviderAction": relayRewardPacketsToProviderAction{},
"main.registerConsumerRewardDenomAction": registerConsumerRewardDenomAction{},
"main.downtimeSlashAction": downtimeSlashAction{},
"main.unbondTokensAction": unbondTokensAction{},
"main.cancelUnbondTokensAction": cancelUnbondTokensAction{},
"main.redelegateTokensAction": redelegateTokensAction{},
"main.doublesignSlashAction": doublesignSlashAction{},
"main.startRelayerAction": startRelayerAction{},
"main.slashThrottleDequeue": slashThrottleDequeue{},
"main.createIbcClientsAction": createIbcClientsAction{},
"main.LegacyUpgradeProposalAction": LegacyUpgradeProposalAction{},
"main.waitUntilBlockAction": waitUntilBlockAction{},
"main.ChangeoverChainAction": ChangeoverChainAction{},
"main.StartSovereignChainAction": StartSovereignChainAction{},
var actionRegistry = map[string]reflect.Type{
"main.submitConsumerAdditionProposalAction": reflect.TypeOf(submitConsumerAdditionProposalAction{}),
"main.SendTokensAction": reflect.TypeOf(SendTokensAction{}),
"main.StartChainAction": reflect.TypeOf(StartChainAction{}),
"main.submitTextProposalAction": reflect.TypeOf(submitTextProposalAction{}),
"main.submitConsumerRemovalProposalAction": reflect.TypeOf(submitConsumerRemovalProposalAction{}),
"main.submitEquivocationProposalAction": reflect.TypeOf(submitEquivocationProposalAction{}),
"main.submitParamChangeLegacyProposalAction": reflect.TypeOf(submitParamChangeLegacyProposalAction{}),
"main.voteGovProposalAction": reflect.TypeOf(voteGovProposalAction{}),
"main.startConsumerChainAction": reflect.TypeOf(startConsumerChainAction{}),
"main.AddChainToRelayerAction": reflect.TypeOf(addChainToRelayerAction{}),
"main.addIbcConnectionAction": reflect.TypeOf(addIbcConnectionAction{}),
"main.addIbcChannelAction": reflect.TypeOf(addIbcChannelAction{}),
"main.transferChannelCompleteAction": reflect.TypeOf(transferChannelCompleteAction{}),
"main.unjailValidatorAction": reflect.TypeOf(unjailValidatorAction{}),
"main.assignConsumerPubKeyAction": reflect.TypeOf(assignConsumerPubKeyAction{}),
"main.delegateTokensAction": reflect.TypeOf(delegateTokensAction{}),
"main.relayPacketsAction": reflect.TypeOf(relayPacketsAction{}),
"main.registerRepresentativeAction": reflect.TypeOf(registerRepresentativeAction{}),
"main.relayRewardPacketsToProviderAction": reflect.TypeOf(relayRewardPacketsToProviderAction{}),
"main.registerConsumerRewardDenomAction": reflect.TypeOf(registerConsumerRewardDenomAction{}),
"main.downtimeSlashAction": reflect.TypeOf(downtimeSlashAction{}),
"main.unbondTokensAction": reflect.TypeOf(unbondTokensAction{}),
"main.cancelUnbondTokensAction": reflect.TypeOf(cancelUnbondTokensAction{}),
"main.redelegateTokensAction": reflect.TypeOf(redelegateTokensAction{}),
"main.doublesignSlashAction": reflect.TypeOf(doublesignSlashAction{}),
"main.startRelayerAction": reflect.TypeOf(startRelayerAction{}),
"main.slashThrottleDequeue": reflect.TypeOf(slashThrottleDequeue{}),
"main.createIbcClientsAction": reflect.TypeOf(createIbcClientsAction{}),
"main.LegacyUpgradeProposalAction": reflect.TypeOf(LegacyUpgradeProposalAction{}),
"main.waitUntilBlockAction": reflect.TypeOf(waitUntilBlockAction{}),
"main.ChangeoverChainAction": reflect.TypeOf(ChangeoverChainAction{}),
"main.StartSovereignChainAction": reflect.TypeOf(StartSovereignChainAction{}),
}

// UnmarshalMapToActionType takes a JSON object and an action type and marshals into an object of the corresponding action.
func UnmarshalMapToActionType(inputMap json.RawMessage, actionType string) (interface{}, error) {
actionStruct, ok := actionRegistry[actionType]
func UnmarshalMapToActionType(rawAction json.RawMessage, actionTypeString string) (interface{}, error) {
actionType, ok := actionRegistry[actionTypeString]
if !ok {
return nil, fmt.Errorf("%s is not a known action type", actionType)
return nil, fmt.Errorf("%s is not a known action type", actionTypeString)
}
err := mapstructure.Decode(inputMap, &actionStruct)

actionStruct := reflect.Zero(actionType).Interface()
err := json.Unmarshal(rawAction, &actionStruct)
if err != nil {
return nil, err
}
return actionStruct, nil
}

// for marshalling/unmarshalling proposals
type ProposalAndType struct {
RawProposal json.RawMessage
Type string
}

type ChainStateWithProposalTypes struct {
ValBalances *map[ValidatorID]uint
ValPowers *map[ValidatorID]uint
RepresentativePowers *map[ValidatorID]uint
Params *[]Param
Rewards *Rewards
ConsumerChains *map[ChainID]bool
AssignedKeys *map[ValidatorID]string
ProviderKeys *map[ValidatorID]string
ConsumerChainQueueSizes *map[ChainID]uint
GlobalSlashQueueSize *uint
RegisteredConsumerRewardDenoms *[]string
Proposals *map[uint]ProposalAndType // the only thing changed from the real ChainState
}

// custom marshal and unmarshal functions for the chainstate that convert proposals to/from the auxiliary type with type info

// transform the ChainState into a ChainStateWithProposalTypes by adding type info to the proposals
func (c ChainState) MarshalJSON() ([]byte, error) {
type ProposalAndType struct {
RawProposal interface{}
Type string
}

type ChainStateWithProposalTypes struct {
ValBalances *map[ValidatorID]uint
ValPowers *map[ValidatorID]uint
RepresentativePowers *map[ValidatorID]uint
Params *[]Param
Rewards *Rewards
ConsumerChains *map[ChainID]bool
AssignedKeys *map[ValidatorID]string
ProviderKeys *map[ValidatorID]string
ConsumerChainQueueSizes *map[ChainID]uint
GlobalSlashQueueSize *uint
RegisteredConsumerRewardDenoms *[]string
Proposals *map[uint]ProposalAndType // the only thing changed from the real ChainState
}

chainStateWithProposalTypes := ChainStateWithProposalTypes{
ValBalances: c.ValBalances,
ValPowers: c.ValPowers,
Expand All @@ -136,12 +135,7 @@ func (c ChainState) MarshalJSON() ([]byte, error) {
if c.Proposals != nil {
proposalsWithTypes := make(map[uint]ProposalAndType)
for k, v := range *c.Proposals {
rawProposal := make(map[string]any)
err := mapstructure.Decode(v, &rawProposal)
if err != nil {
return nil, err
}
proposalsWithTypes[k] = ProposalAndType{rawProposal, reflect.TypeOf(v).String()}
proposalsWithTypes[k] = ProposalAndType{v, reflect.TypeOf(v).String()}
}
chainStateWithProposalTypes.Proposals = &proposalsWithTypes
}
Expand All @@ -150,6 +144,26 @@ func (c ChainState) MarshalJSON() ([]byte, error) {

// unmarshal the ChainStateWithProposalTypes into a ChainState by removing the type info from the proposals and getting back standard proposals
func (c *ChainState) UnmarshalJSON(data []byte) error {
type ProposalAndType struct {
RawProposal json.RawMessage
Type string
}

type ChainStateWithProposalTypes struct {
ValBalances *map[ValidatorID]uint
ValPowers *map[ValidatorID]uint
RepresentativePowers *map[ValidatorID]uint
Params *[]Param
Rewards *Rewards
ConsumerChains *map[ChainID]bool
AssignedKeys *map[ValidatorID]string
ProviderKeys *map[ValidatorID]string
ConsumerChainQueueSizes *map[ChainID]uint
GlobalSlashQueueSize *uint
RegisteredConsumerRewardDenoms *[]string
Proposals *map[uint]ProposalAndType // the only thing changed from the real ChainState
}

chainStateWithProposalTypes := ChainStateWithProposalTypes{}
err := json.Unmarshal(data, &chainStateWithProposalTypes)
if err != nil {
Expand Down Expand Up @@ -197,7 +211,7 @@ func UnmarshalProposalWithType(inputMap json.RawMessage, proposalType string) (P
if !ok {
return nil, fmt.Errorf("%s is not a known proposal type", proposalType)
}
err := mapstructure.Decode(inputMap, &propStruct)
err := json.Unmarshal(inputMap, &propStruct)
if err != nil {
return nil, err
}
Expand Down
2 changes: 1 addition & 1 deletion tests/e2e/trace_handlers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ func TestWriterThenParser(t *testing.T) {
trace []Step
}{
"proposalSubmission": {proposalSubmissionSteps},
// "proposalInState": {proposalInStateSteps},
// "proposalInState": {proposalInStateSteps},
// "start_provider_chain": {stepStartProviderChain()},
// "happyPath": {happyPathSteps},
// "democracy": {democracySteps},
Expand Down
Loading

0 comments on commit 91c97aa

Please sign in to comment.