mirror of
				https://github.com/0glabs/0g-chain.git
				synced 2025-11-04 03:57:44 +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 (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"net/http"
 | 
			
		||||
	"strings"
 | 
			
		||||
 | 
			
		||||
	"github.com/gorilla/mux"
 | 
			
		||||
 | 
			
		||||
@ -13,6 +14,7 @@ import (
 | 
			
		||||
	"github.com/cosmos/cosmos-sdk/types/rest"
 | 
			
		||||
	"github.com/cosmos/cosmos-sdk/x/auth"
 | 
			
		||||
	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"
 | 
			
		||||
	"github.com/cosmos/cosmos-sdk/x/auth/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"
 | 
			
		||||
	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"
 | 
			
		||||
	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.HandleFunc("/node_info", rpc.NodeInfoRequestHandlerFn(cliCtx)).Methods("GET")
 | 
			
		||||
	s.HandleFunc(
 | 
			
		||||
		"/auth/accounts/{address}", QueryAccountRequestHandlerFn(cliCtx),
 | 
			
		||||
	).Methods("GET")
 | 
			
		||||
	s.HandleFunc("/txs/{hash}", authrest.QueryTxRequestHandlerFn(cliCtx)).Methods("GET")
 | 
			
		||||
	// r.HandleFunc("/txs", QueryTxsRequestHandlerFn(cliCtx)).Methods("GET") // assume they don't need GET here
 | 
			
		||||
 | 
			
		||||
	s.HandleFunc("/auth/accounts/{address}", QueryAccountRequestHandlerFn(cliCtx)).Methods("GET")
 | 
			
		||||
 | 
			
		||||
	s.HandleFunc("/txs/{hash}", QueryTxRequestHandlerFn(cliCtx)).Methods("GET")
 | 
			
		||||
	// r.HandleFunc("/txs", QueryTxsRequestHandlerFn(cliCtx)).Methods("GET") // TODO does trust wallet query txs?
 | 
			
		||||
	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
 | 
			
		||||
	s.HandleFunc(
 | 
			
		||||
		"/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
 | 
			
		||||
// 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 {
 | 
			
		||||
@ -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 {
 | 
			
		||||
	v0_3Codec := codec.New()
 | 
			
		||||
	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