From e6e7ad581a054266f339ec9b9fc58fafa85fe9dd Mon Sep 17 00:00:00 2001 From: Andrew Gaffney Date: Sun, 27 Nov 2022 15:07:48 -0600 Subject: [PATCH] feat: flesh out query result types This was supposed to cover a lot more, but many of the result types are either poorly documented or we cannot currently parse due to maps with bytestring keys Fixes #134 --- cmd/go-ouroboros-network/query.go | 26 ++++++- protocol/localstatequery/client.go | 49 ++++++------ protocol/localstatequery/queries.go | 115 +++++++++++++++++++++++++++- 3 files changed, 161 insertions(+), 29 deletions(-) diff --git a/cmd/go-ouroboros-network/query.go b/cmd/go-ouroboros-network/query.go index 4b9a1c7e..6d1b97f1 100644 --- a/cmd/go-ouroboros-network/query.go +++ b/cmd/go-ouroboros-network/query.go @@ -101,7 +101,31 @@ func testQuery(f *globalFlags) { fmt.Printf("ERROR: failure querying era history: %s\n", err) os.Exit(1) } - fmt.Printf("era-history: %#v", *eraHistory) + fmt.Printf("era-history:\n") + for eraId, era := range eraHistory { + fmt.Printf("id = %d, begin slot/epoch = %d/%d, end slot/epoch = %d/%d, epoch length = %d, slot length (ms) = %d, slots per KES period = %d\n", eraId, era.Begin.SlotNo, era.Begin.EpochNo, era.End.SlotNo, era.End.EpochNo, era.Params.EpochLength, era.Params.SlotLength, era.Params.SlotsPerKESPeriod.Value) + } + case "protocol-params": + protoParams, err := o.LocalStateQuery.Client.GetCurrentProtocolParams() + if err != nil { + fmt.Printf("ERROR: failure querying protocol params: %s\n", err) + os.Exit(1) + } + fmt.Printf("protocol-params: %#v\n", *protoParams) + case "stake-distribution": + stakeDistribution, err := o.LocalStateQuery.Client.GetStakeDistribution() + if err != nil { + fmt.Printf("ERROR: failure querying stake distribution: %s\n", err) + os.Exit(1) + } + fmt.Printf("stake-distribution: %#v\n", *stakeDistribution) + case "genesis-config": + genesisConfig, err := o.LocalStateQuery.Client.GetGenesisConfig() + if err != nil { + fmt.Printf("ERROR: failure querying genesis config: %s\n", err) + os.Exit(1) + } + fmt.Printf("genesis-config: %#v\n", *genesisConfig) default: fmt.Printf("ERROR: unknown query: %s\n", queryFlags.flagset.Args()[0]) os.Exit(1) diff --git a/protocol/localstatequery/client.go b/protocol/localstatequery/client.go index 452f8171..d614ba7d 100644 --- a/protocol/localstatequery/client.go +++ b/protocol/localstatequery/client.go @@ -215,15 +215,15 @@ func (c *Client) GetChainPoint() (*common.Point, error) { return &result, nil } -func (c *Client) GetEraHistory() (*EraHistoryResult, error) { +func (c *Client) GetEraHistory() ([]EraHistoryResult, error) { c.busyMutex.Lock() defer c.busyMutex.Unlock() query := buildHardForkQuery(QUERY_TYPE_HARD_FORK_ERA_HISTORY) - var result EraHistoryResult + var result []EraHistoryResult if err := c.runQuery(query, &result); err != nil { - return nil, err + return []EraHistoryResult{}, err } - return &result, nil + return result, nil } func (c *Client) GetEpochNo() (int, error) { @@ -244,6 +244,7 @@ func (c *Client) GetEpochNo() (int, error) { return result[0], nil } +// TODO func (c *Client) GetNonMyopicMemberRewards() (*NonMyopicMemberRewardsResult, error) { c.busyMutex.Lock() defer c.busyMutex.Unlock() @@ -273,14 +274,15 @@ func (c *Client) GetCurrentProtocolParams() (*CurrentProtocolParamsResult, error currentEra, QUERY_TYPE_SHELLEY_CURRENT_PROTOCOL_PARAMS, ) - var result CurrentProtocolParamsResult + var result []CurrentProtocolParamsResult if err := c.runQuery(query, &result); err != nil { return nil, err } - return &result, nil + return &result[0], nil } +// TODO func (c *Client) GetProposedProtocolParamsUpdates() (*ProposedProtocolParamsUpdatesResult, error) { c.busyMutex.Lock() defer c.busyMutex.Unlock() @@ -316,9 +318,9 @@ func (c *Client) GetStakeDistribution() (*StakeDistributionResult, error) { return nil, err } return &result, nil - } +// TODO func (c *Client) GetUTxOByAddress(addrs []interface{}) (*UTxOByAddressResult, error) { c.busyMutex.Lock() defer c.busyMutex.Unlock() @@ -335,9 +337,9 @@ func (c *Client) GetUTxOByAddress(addrs []interface{}) (*UTxOByAddressResult, er return nil, err } return &result, nil - } +// TODO func (c *Client) GetUTxOWhole() (*UTxOWholeResult, error) { c.busyMutex.Lock() defer c.busyMutex.Unlock() @@ -354,9 +356,9 @@ func (c *Client) GetUTxOWhole() (*UTxOWholeResult, error) { return nil, err } return &result, nil - } +// TODO func (c *Client) DebugEpochState() (*DebugEpochStateResult, error) { c.busyMutex.Lock() defer c.busyMutex.Unlock() @@ -373,9 +375,9 @@ func (c *Client) DebugEpochState() (*DebugEpochStateResult, error) { return nil, err } return &result, nil - } +// TODO func (c *Client) GetFilteredDelegationsAndRewardAccounts(creds []interface{}) (*FilteredDelegationsAndRewardAccountsResult, error) { c.busyMutex.Lock() defer c.busyMutex.Unlock() @@ -392,9 +394,9 @@ func (c *Client) GetFilteredDelegationsAndRewardAccounts(creds []interface{}) (* return nil, err } return &result, nil - } +// TODO func (c *Client) GetGenesisConfig() (*GenesisConfigResult, error) { c.busyMutex.Lock() defer c.busyMutex.Unlock() @@ -406,14 +408,14 @@ func (c *Client) GetGenesisConfig() (*GenesisConfigResult, error) { currentEra, QUERY_TYPE_SHELLEY_GENESIS_CONFIG, ) - var result GenesisConfigResult + var result []GenesisConfigResult if err := c.runQuery(query, &result); err != nil { return nil, err } - return &result, nil - + return &result[0], nil } +// TODO func (c *Client) DebugNewEpochState() (*DebugNewEpochStateResult, error) { c.busyMutex.Lock() defer c.busyMutex.Unlock() @@ -430,9 +432,9 @@ func (c *Client) DebugNewEpochState() (*DebugNewEpochStateResult, error) { return nil, err } return &result, nil - } +// TODO func (c *Client) DebugChainDepState() (*DebugChainDepStateResult, error) { c.busyMutex.Lock() defer c.busyMutex.Unlock() @@ -449,9 +451,9 @@ func (c *Client) DebugChainDepState() (*DebugChainDepStateResult, error) { return nil, err } return &result, nil - } +// TODO func (c *Client) GetRewardProvenance() (*RewardProvenanceResult, error) { c.busyMutex.Lock() defer c.busyMutex.Unlock() @@ -468,9 +470,9 @@ func (c *Client) GetRewardProvenance() (*RewardProvenanceResult, error) { return nil, err } return &result, nil - } +// TODO func (c *Client) GetUTxOByTxIn(txins []interface{}) (*UTxOByTxInResult, error) { c.busyMutex.Lock() defer c.busyMutex.Unlock() @@ -487,9 +489,9 @@ func (c *Client) GetUTxOByTxIn(txins []interface{}) (*UTxOByTxInResult, error) { return nil, err } return &result, nil - } +// TODO func (c *Client) GetStakePools() (*StakePoolsResult, error) { c.busyMutex.Lock() defer c.busyMutex.Unlock() @@ -506,9 +508,9 @@ func (c *Client) GetStakePools() (*StakePoolsResult, error) { return nil, err } return &result, nil - } +// TODO func (c *Client) GetStakePoolParams(poolIds []interface{}) (*StakePoolParamsResult, error) { c.busyMutex.Lock() defer c.busyMutex.Unlock() @@ -525,9 +527,9 @@ func (c *Client) GetStakePoolParams(poolIds []interface{}) (*StakePoolParamsResu return nil, err } return &result, nil - } +// TODO func (c *Client) GetRewardInfoPools() (*RewardInfoPoolsResult, error) { c.busyMutex.Lock() defer c.busyMutex.Unlock() @@ -544,9 +546,9 @@ func (c *Client) GetRewardInfoPools() (*RewardInfoPoolsResult, error) { return nil, err } return &result, nil - } +// TODO func (c *Client) GetPoolState(poolIds []interface{}) (*PoolStateResult, error) { c.busyMutex.Lock() defer c.busyMutex.Unlock() @@ -563,9 +565,9 @@ func (c *Client) GetPoolState(poolIds []interface{}) (*PoolStateResult, error) { return nil, err } return &result, nil - } +// TODO func (c *Client) GetStakeSnapshots(poolId interface{}) (*StakeSnapshotsResult, error) { c.busyMutex.Lock() defer c.busyMutex.Unlock() @@ -582,9 +584,9 @@ func (c *Client) GetStakeSnapshots(poolId interface{}) (*StakeSnapshotsResult, e return nil, err } return &result, nil - } +// TODO func (c *Client) GetPoolDistr(poolIds []interface{}) (*PoolDistrResult, error) { c.busyMutex.Lock() defer c.busyMutex.Unlock() @@ -601,5 +603,4 @@ func (c *Client) GetPoolDistr(poolIds []interface{}) (*PoolDistrResult, error) { return nil, err } return &result, nil - } diff --git a/protocol/localstatequery/queries.go b/protocol/localstatequery/queries.go index 3e334b10..8b88ca90 100644 --- a/protocol/localstatequery/queries.go +++ b/protocol/localstatequery/queries.go @@ -1,5 +1,9 @@ package localstatequery +import ( + "github.com/fxamacker/cbor/v2" +) + const ( QUERY_TYPE_BLOCK = 0 QUERY_TYPE_SYSTEM_START = 1 @@ -86,17 +90,120 @@ type SystemStartResult struct { Picoseconds uint64 } -// TODO: populate me -type EraHistoryResult interface{} +type EraHistoryResult struct { + // Tells the CBOR decoder to convert to/from a struct and a CBOR array + _ struct{} `cbor:",toarray"` + Begin eraHistoryResultBeginEnd + End eraHistoryResultBeginEnd + Params eraHistoryResultParams +} + +type eraHistoryResultBeginEnd struct { + // Tells the CBOR decoder to convert to/from a struct and a CBOR array + _ struct{} `cbor:",toarray"` + Timespan interface{} + SlotNo int + EpochNo int +} + +type eraHistoryResultParams struct { + // Tells the CBOR decoder to convert to/from a struct and a CBOR array + _ struct{} `cbor:",toarray"` + EpochLength int + SlotLength int + SlotsPerKESPeriod struct { + // Tells the CBOR decoder to convert to/from a struct and a CBOR array + _ struct{} `cbor:",toarray"` + Dummy1 interface{} + Value int + Dummy2 interface{} + } +} + +// TODO type NonMyopicMemberRewardsResult interface{} -type CurrentProtocolParamsResult interface{} + +type CurrentProtocolParamsResult struct { + // Tells the CBOR decoder to convert to/from a struct and a CBOR array + _ struct{} `cbor:",toarray"` + MinFeeA int + MinFeeB int + MaxBlockBodySize int + MaxTxSize int + MaxBlockHeaderSize int + KeyDeposit int + PoolDeposit int + EMax int + NOpt int + A0 []int + Rho []int + Tau []int + // This field no longer exists in Babbage, but we're keeping this here for reference + // unless we need to support querying a node still on an older era + //DecentralizationParam []int + ProtocolVersionMajor int + ProtocolVersionMinor int + MinPoolCost int + Unknown interface{} + CostModels interface{} + ExecutionUnitPrices interface{} // [priceMemory priceSteps] both elements are fractions + MaxTxExecutionUnits []uint + MaxBlockExecutionUnits []uint + MaxValueSize int + CollateralPercentage int +} + +// TODO type ProposedProtocolParamsUpdatesResult interface{} type StakeDistributionResult interface{} type UTxOByAddressResult interface{} type UTxOWholeResult interface{} type DebugEpochStateResult interface{} type FilteredDelegationsAndRewardAccountsResult interface{} -type GenesisConfigResult interface{} + +type GenesisConfigResult struct { + // Tells the CBOR decoder to convert to/from a struct and a CBOR array + _ struct{} `cbor:",toarray"` + Start SystemStartResult + NetworkMagic int + NetworkId uint8 + ActiveSlotsCoeff []interface{} + SecurityParam int + EpochLength int + SlotsPerKESPeriod int + MaxKESEvolutions int + SlotLength int + UpdateQuorum int + MaxLovelaceSupply int64 + ProtocolParams struct { + // Tells the CBOR decoder to convert to/from a struct and a CBOR array + _ struct{} `cbor:",toarray"` + MinFeeA int + MinFeeB int + MaxBlockBodySize int + MaxTxSize int + MaxBlockHeaderSize int + KeyDeposit int + PoolDeposit int + EMax int + NOpt int + A0 []int + Rho []int + Tau []int + DecentralizationParam []int + ExtraEntropy interface{} + ProtocolVersionMajor int + ProtocolVersionMinor int + MinUTxOValue int + MinPoolCost int + } + // This value contains maps with bytestring keys, which we can't parse yet + GenDelegs cbor.RawMessage + Unknown1 interface{} + Unknown2 interface{} +} + +// TODO type DebugNewEpochStateResult interface{} type DebugChainDepStateResult interface{} type RewardProvenanceResult interface{}