mirror of
https://github.com/0glabs/0g-chain.git
synced 2024-12-24 23:35:19 +00:00
Add legacy block and tx rest endpoints (#602)
* add block and tx endpoints * add block legacy endpoint
This commit is contained in:
parent
97a51479f6
commit
d83c43dcb4
@ -3,6 +3,7 @@ package rest_v0_3
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
|
|
||||||
@ -13,6 +14,7 @@ import (
|
|||||||
"github.com/cosmos/cosmos-sdk/types/rest"
|
"github.com/cosmos/cosmos-sdk/types/rest"
|
||||||
"github.com/cosmos/cosmos-sdk/x/auth"
|
"github.com/cosmos/cosmos-sdk/x/auth"
|
||||||
authrest "github.com/cosmos/cosmos-sdk/x/auth/client/rest"
|
authrest "github.com/cosmos/cosmos-sdk/x/auth/client/rest"
|
||||||
|
"github.com/cosmos/cosmos-sdk/x/auth/client/utils"
|
||||||
authexported "github.com/cosmos/cosmos-sdk/x/auth/exported"
|
authexported "github.com/cosmos/cosmos-sdk/x/auth/exported"
|
||||||
"github.com/cosmos/cosmos-sdk/x/auth/types"
|
"github.com/cosmos/cosmos-sdk/x/auth/types"
|
||||||
vestingtypes "github.com/cosmos/cosmos-sdk/x/auth/vesting/types"
|
vestingtypes "github.com/cosmos/cosmos-sdk/x/auth/vesting/types"
|
||||||
@ -22,6 +24,9 @@ import (
|
|||||||
|
|
||||||
v18de63auth "github.com/kava-labs/kava/migrate/v0_8/sdk/auth/v18de63"
|
v18de63auth "github.com/kava-labs/kava/migrate/v0_8/sdk/auth/v18de63"
|
||||||
v18de63supply "github.com/kava-labs/kava/migrate/v0_8/sdk/supply/v18de63"
|
v18de63supply "github.com/kava-labs/kava/migrate/v0_8/sdk/supply/v18de63"
|
||||||
|
v18de63sdk "github.com/kava-labs/kava/migrate/v0_8/sdk/types"
|
||||||
|
v032tendermint "github.com/kava-labs/kava/migrate/v0_8/tendermint/v0_32"
|
||||||
|
v032tendermintrpc "github.com/kava-labs/kava/migrate/v0_8/tendermint/v0_32/rpccore"
|
||||||
valvesting "github.com/kava-labs/kava/x/validator-vesting"
|
valvesting "github.com/kava-labs/kava/x/validator-vesting"
|
||||||
v0_3valvesting "github.com/kava-labs/kava/x/validator-vesting/legacy/v0_3"
|
v0_3valvesting "github.com/kava-labs/kava/x/validator-vesting/legacy/v0_3"
|
||||||
)
|
)
|
||||||
@ -30,13 +35,16 @@ func RegisterRoutes(cliCtx context.CLIContext, r *mux.Router) {
|
|||||||
s := r.PathPrefix("/v0_3").Subrouter()
|
s := r.PathPrefix("/v0_3").Subrouter()
|
||||||
|
|
||||||
s.HandleFunc("/node_info", rpc.NodeInfoRequestHandlerFn(cliCtx)).Methods("GET")
|
s.HandleFunc("/node_info", rpc.NodeInfoRequestHandlerFn(cliCtx)).Methods("GET")
|
||||||
s.HandleFunc(
|
|
||||||
"/auth/accounts/{address}", QueryAccountRequestHandlerFn(cliCtx),
|
s.HandleFunc("/auth/accounts/{address}", QueryAccountRequestHandlerFn(cliCtx)).Methods("GET")
|
||||||
).Methods("GET")
|
|
||||||
s.HandleFunc("/txs/{hash}", authrest.QueryTxRequestHandlerFn(cliCtx)).Methods("GET")
|
s.HandleFunc("/txs/{hash}", QueryTxRequestHandlerFn(cliCtx)).Methods("GET")
|
||||||
// r.HandleFunc("/txs", QueryTxsRequestHandlerFn(cliCtx)).Methods("GET") // assume they don't need GET here
|
// r.HandleFunc("/txs", QueryTxsRequestHandlerFn(cliCtx)).Methods("GET") // TODO does trust wallet query txs?
|
||||||
s.HandleFunc("/txs", authrest.BroadcastTxRequest(cliCtx)).Methods("POST")
|
s.HandleFunc("/txs", authrest.BroadcastTxRequest(cliCtx)).Methods("POST")
|
||||||
|
|
||||||
|
s.HandleFunc("/blocks/latest", LatestBlockRequestHandlerFn(cliCtx)).Methods("GET")
|
||||||
|
|
||||||
|
// These endpoints are unchanged between cosmos v18de63 and v0.38.4, but can't import private methods so copy and pasting handler methods.
|
||||||
// Get all delegations from a delegator
|
// Get all delegations from a delegator
|
||||||
s.HandleFunc(
|
s.HandleFunc(
|
||||||
"/staking/delegators/{delegatorAddr}/delegations",
|
"/staking/delegators/{delegatorAddr}/delegations",
|
||||||
@ -57,6 +65,73 @@ func RegisterRoutes(cliCtx context.CLIContext, r *mux.Router) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// REST handler to get the latest block
|
||||||
|
func LatestBlockRequestHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
|
||||||
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
output, err := getBlock(cliCtx, nil)
|
||||||
|
if err != nil {
|
||||||
|
rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
rest.PostProcessResponseBare(w, cliCtx, output)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func getBlock(cliCtx context.CLIContext, height *int64) ([]byte, error) {
|
||||||
|
// get the node
|
||||||
|
node, err := cliCtx.GetNode()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
res, err := node.Block(height)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert block to old type
|
||||||
|
header := v032tendermint.Header{
|
||||||
|
Version: v032tendermint.Consensus{
|
||||||
|
Block: v032tendermint.Protocol(res.Block.Header.Version.Block),
|
||||||
|
App: v032tendermint.Protocol(res.Block.Header.Version.App),
|
||||||
|
},
|
||||||
|
ChainID: res.Block.Header.ChainID,
|
||||||
|
Height: res.Block.Header.Height,
|
||||||
|
Time: res.Block.Header.Time,
|
||||||
|
NumTxs: 0, // trust wallet doesn't use this field
|
||||||
|
TotalTxs: 0, // trust wallet doesn't use this field
|
||||||
|
|
||||||
|
LastBlockID: res.Block.Header.LastBlockID,
|
||||||
|
|
||||||
|
LastCommitHash: res.Block.Header.LastCommitHash,
|
||||||
|
DataHash: res.Block.Header.DataHash,
|
||||||
|
ValidatorsHash: res.Block.Header.ValidatorsHash,
|
||||||
|
NextValidatorsHash: res.Block.Header.NextValidatorsHash,
|
||||||
|
ConsensusHash: res.Block.Header.ConsensusHash,
|
||||||
|
AppHash: res.Block.Header.AppHash,
|
||||||
|
LastResultsHash: res.Block.Header.LastResultsHash,
|
||||||
|
EvidenceHash: res.Block.Header.EvidenceHash,
|
||||||
|
ProposerAddress: res.Block.Header.ProposerAddress,
|
||||||
|
}
|
||||||
|
block := v032tendermint.Block{
|
||||||
|
Header: header,
|
||||||
|
Data: res.Block.Data,
|
||||||
|
Evidence: res.Block.Evidence,
|
||||||
|
LastCommit: nil, // trust wallet doesn't need to access commit info
|
||||||
|
}
|
||||||
|
blockMeta := v032tendermint.BlockMeta{
|
||||||
|
BlockID: res.BlockID,
|
||||||
|
Header: header,
|
||||||
|
}
|
||||||
|
oldResponse := v032tendermintrpc.ResultBlock{
|
||||||
|
Block: &block,
|
||||||
|
BlockMeta: &blockMeta,
|
||||||
|
}
|
||||||
|
|
||||||
|
return codec.Cdc.MarshalJSON(oldResponse)
|
||||||
|
}
|
||||||
|
|
||||||
// QueryAccountRequestHandlerFn handle auth/accounts queries
|
// QueryAccountRequestHandlerFn handle auth/accounts queries
|
||||||
// This function is identical to v0.8 except the queried account is cast to the v0.3 account type so it marshals in the old format.
|
// This function is identical to v0.8 except the queried account is cast to the v0.3 account type so it marshals in the old format.
|
||||||
func QueryAccountRequestHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
|
func QueryAccountRequestHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
|
||||||
@ -100,6 +175,61 @@ func QueryAccountRequestHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// QueryTxRequestHandlerFn implements a REST handler that queries a transaction
|
||||||
|
// by hash in a committed block.
|
||||||
|
func QueryTxRequestHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
|
||||||
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
vars := mux.Vars(r)
|
||||||
|
hashHexStr := vars["hash"]
|
||||||
|
|
||||||
|
cliCtx, ok := rest.ParseQueryHeightOrReturnBadRequest(w, cliCtx, r)
|
||||||
|
if !ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
output, err := utils.QueryTx(cliCtx, hashHexStr)
|
||||||
|
if err != nil {
|
||||||
|
if strings.Contains(err.Error(), hashHexStr) {
|
||||||
|
rest.WriteErrorResponse(w, http.StatusNotFound, err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// convert v0.8 TxResponse to a v0.3 Tx Response
|
||||||
|
oldOutput := rollbackTxResponseType(output)
|
||||||
|
if oldOutput.Empty() {
|
||||||
|
rest.WriteErrorResponse(w, http.StatusNotFound, fmt.Sprintf("no transaction found with hash %s", hashHexStr))
|
||||||
|
}
|
||||||
|
|
||||||
|
rest.PostProcessResponseBare(w, cliCtx, oldOutput)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func rollbackTxResponseType(response sdk.TxResponse) v18de63sdk.TxResponse {
|
||||||
|
events := sdk.StringEvents{}
|
||||||
|
for _, msgLog := range response.Logs {
|
||||||
|
events = append(events, msgLog.Events...)
|
||||||
|
}
|
||||||
|
return v18de63sdk.TxResponse{
|
||||||
|
Height: response.Height,
|
||||||
|
TxHash: response.TxHash,
|
||||||
|
Codespace: response.Codespace,
|
||||||
|
Code: response.Code,
|
||||||
|
Data: response.Data,
|
||||||
|
RawLog: response.RawLog,
|
||||||
|
Logs: nil, // trust wallet doesn't use logs, so leaving them out
|
||||||
|
Info: response.Info,
|
||||||
|
GasWanted: response.GasWanted,
|
||||||
|
GasUsed: response.GasUsed,
|
||||||
|
Tx: response.Tx,
|
||||||
|
Timestamp: response.Timestamp,
|
||||||
|
Events: events,
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
func makeCodecV03() *codec.Codec {
|
func makeCodecV03() *codec.Codec {
|
||||||
v0_3Codec := codec.New()
|
v0_3Codec := codec.New()
|
||||||
codec.RegisterCrypto(v0_3Codec)
|
codec.RegisterCrypto(v0_3Codec)
|
||||||
|
42
migrate/v0_8/sdk/types/result.go
Normal file
42
migrate/v0_8/sdk/types/result.go
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
package types
|
||||||
|
|
||||||
|
import (
|
||||||
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
// TxResponse defines a structure containing relevant tx data and metadata. The
|
||||||
|
// tags are stringified and the log is JSON decoded.
|
||||||
|
type TxResponse struct {
|
||||||
|
Height int64 `json:"height"`
|
||||||
|
TxHash string `json:"txhash"`
|
||||||
|
Code uint32 `json:"code,omitempty"`
|
||||||
|
Data string `json:"data,omitempty"`
|
||||||
|
RawLog string `json:"raw_log,omitempty"`
|
||||||
|
Logs ABCIMessageLogs `json:"logs,omitempty"`
|
||||||
|
Info string `json:"info,omitempty"`
|
||||||
|
GasWanted int64 `json:"gas_wanted,omitempty"`
|
||||||
|
GasUsed int64 `json:"gas_used,omitempty"`
|
||||||
|
Codespace string `json:"codespace,omitempty"`
|
||||||
|
Tx sdk.Tx `json:"tx,omitempty"`
|
||||||
|
Timestamp string `json:"timestamp,omitempty"`
|
||||||
|
Events sdk.StringEvents `json:"events,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Empty returns true if the response is empty
|
||||||
|
func (r TxResponse) Empty() bool {
|
||||||
|
return r.TxHash == "" && r.Logs == nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ABCIMessageLogs represents a slice of ABCIMessageLog.
|
||||||
|
type ABCIMessageLogs []ABCIMessageLog
|
||||||
|
|
||||||
|
// ABCIMessageLog defines a structure containing an indexed tx ABCI message log.
|
||||||
|
type ABCIMessageLog struct {
|
||||||
|
MsgIndex uint16 `json:"msg_index"`
|
||||||
|
Success bool `json:"success"`
|
||||||
|
Log string `json:"log"`
|
||||||
|
|
||||||
|
// Events contains a slice of Event objects that were emitted during some
|
||||||
|
// execution.
|
||||||
|
Events sdk.StringEvents `json:"events"`
|
||||||
|
}
|
52
migrate/v0_8/tendermint/v0_32/block.go
Normal file
52
migrate/v0_8/tendermint/v0_32/block.go
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
package v032
|
||||||
|
|
||||||
|
import (
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
tmbytes "github.com/tendermint/tendermint/libs/bytes"
|
||||||
|
tmtypes "github.com/tendermint/tendermint/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Block defines the atomic unit of a Tendermint blockchain.
|
||||||
|
type Block struct {
|
||||||
|
mtx sync.Mutex
|
||||||
|
Header `json:"header"`
|
||||||
|
Data tmtypes.Data `json:"data"`
|
||||||
|
Evidence tmtypes.EvidenceData `json:"evidence"`
|
||||||
|
LastCommit *Commit `json:"last_commit"` // not using for trust wallet
|
||||||
|
}
|
||||||
|
|
||||||
|
// Header defines the structure of a Tendermint block header.
|
||||||
|
type Header struct {
|
||||||
|
// basic block info
|
||||||
|
Version Consensus `json:"version"`
|
||||||
|
ChainID string `json:"chain_id"`
|
||||||
|
Height int64 `json:"height"`
|
||||||
|
Time time.Time `json:"time"`
|
||||||
|
NumTxs int64 `json:"num_txs"`
|
||||||
|
TotalTxs int64 `json:"total_txs"`
|
||||||
|
|
||||||
|
// prev block info
|
||||||
|
LastBlockID tmtypes.BlockID `json:"last_block_id"`
|
||||||
|
|
||||||
|
// hashes of block data
|
||||||
|
LastCommitHash tmbytes.HexBytes `json:"last_commit_hash"` // commit from validators from the last block
|
||||||
|
DataHash tmbytes.HexBytes `json:"data_hash"` // transactions
|
||||||
|
|
||||||
|
// hashes from the app output from the prev block
|
||||||
|
ValidatorsHash tmbytes.HexBytes `json:"validators_hash"` // validators for the current block
|
||||||
|
NextValidatorsHash tmbytes.HexBytes `json:"next_validators_hash"` // validators for the next block
|
||||||
|
ConsensusHash tmbytes.HexBytes `json:"consensus_hash"` // consensus params for current block
|
||||||
|
AppHash tmbytes.HexBytes `json:"app_hash"` // state after txs from the previous block
|
||||||
|
// root hash of all results from the txs from the previous block
|
||||||
|
LastResultsHash tmbytes.HexBytes `json:"last_results_hash"`
|
||||||
|
|
||||||
|
// consensus info
|
||||||
|
EvidenceHash tmbytes.HexBytes `json:"evidence_hash"` // evidence included in the block
|
||||||
|
ProposerAddress tmtypes.Address `json:"proposer_address"` // original proposer of the block
|
||||||
|
}
|
||||||
|
|
||||||
|
// Commit contains the evidence that a block was committed by a set of validators.
|
||||||
|
type Commit struct {
|
||||||
|
}
|
11
migrate/v0_8/tendermint/v0_32/block_meta.go
Normal file
11
migrate/v0_8/tendermint/v0_32/block_meta.go
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
package v032
|
||||||
|
|
||||||
|
import (
|
||||||
|
tmtypes "github.com/tendermint/tendermint/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
// BlockMeta contains meta information about a block - namely, it's ID and Header.
|
||||||
|
type BlockMeta struct {
|
||||||
|
BlockID tmtypes.BlockID `json:"block_id"` // the block hash and partsethash
|
||||||
|
Header Header `json:"header"` // The block's Header
|
||||||
|
}
|
11
migrate/v0_8/tendermint/v0_32/rpccore/responses.go
Normal file
11
migrate/v0_8/tendermint/v0_32/rpccore/responses.go
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
package rpccore
|
||||||
|
|
||||||
|
import (
|
||||||
|
types "github.com/kava-labs/kava/migrate/v0_8/tendermint/v0_32"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Single block (with meta)
|
||||||
|
type ResultBlock struct {
|
||||||
|
BlockMeta *types.BlockMeta `json:"block_meta"`
|
||||||
|
Block *types.Block `json:"block"`
|
||||||
|
}
|
12
migrate/v0_8/tendermint/v0_32/version.go
Normal file
12
migrate/v0_8/tendermint/v0_32/version.go
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
package v032
|
||||||
|
|
||||||
|
// Protocol is used for implementation agnostic versioning.
|
||||||
|
type Protocol uint64
|
||||||
|
|
||||||
|
// Consensus captures the consensus rules for processing a block in the blockchain,
|
||||||
|
// including all blockchain data structures and the rules of the application's
|
||||||
|
// state transition machine.
|
||||||
|
type Consensus struct {
|
||||||
|
Block Protocol `json:"block"`
|
||||||
|
App Protocol `json:"app"`
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user