The JSON RPC module implements the JSON RPC API layer, something that dApp developers use to interact with the blockchain.
It includes support for standard json-rpc endpoints, as well as websocket endpoints.
Blockchain Interface
TheZchains uses the blockchain interface to define all the methods that the JSON RPC module needs to use, in order to deliver its endpoints.
The blockchain interface is implemented by the Minimal server. It is the base implementation that's passed into the JSON RPC layer.
typeblockchainInterfaceinterface {// Header returns the current header of the chain (genesis if empty)Header() *types.Header// GetReceiptsByHash returns the receipts for a hashGetReceiptsByHash(hash types.Hash) ([]*types.Receipt, error)// Subscribe subscribes for chain head eventsSubscribeEvents() blockchain.Subscription// GetHeaderByNumber returns the header by numberGetHeaderByNumber(block uint64) (*types.Header, bool)// GetAvgGasPrice returns the average gas priceGetAvgGasPrice() *big.Int// AddTx adds a new transaction to the tx poolAddTx(tx *types.Transaction) error// State returns a reference to the stateState() state.State// BeginTxn starts a transition objectBeginTxn(parentRoot types.Hash, header *types.Header) (*state.Transition, error)// GetBlockByHash gets a block using the provided hashGetBlockByHash(hash types.Hash, full bool) (*types.Block, bool)// ApplyTxn applies a transaction object to the blockchainApplyTxn(header *types.Header, txn *types.Transaction) ([]byte, bool, error)stateHelperInterface}
ETH Endpoints
All the standard JSON RPC endpoints are implemented in:
jsonrpc/eth_endpoint.go
Filter Manager
The Filter Manager is a service that runs alongside the JSON RPC server.
It provides support for filtering blocks on the blockchain.
Specifically, it includes both a log and a block level filter.
The Filter Manager relies heavily on Subscription Events, mentioned in the Blockchain section
typeFilterstruct { id string// block filter block *headElem// log cache logs []*Log// log filter logFilter *LogFilter// index of the filter in the timer array index int// next time to timeout timestamp time.Time// websocket connection ws wsConn}typeFilterManagerstruct { logger hclog.Logger store blockchainInterface closeCh chanstruct{} subscription blockchain.Subscription filters map[string]*Filter lock sync.Mutex updateCh chanstruct{} timer timeHeapImpl timeout time.Duration blockStream *blockStream}
Filter Manager events get dispatched in the Run method:
func (f *FilterManager) Run() {// watch for new events in the blockchain watchCh :=make(chan*blockchain.Event)gofunc() {for { evnt := f.subscription.GetEvent()if evnt ==nil {return } watchCh <- evnt } }()var timeoutCh <-chantime.Timefor {// check for the next filter to be removed filter := f.nextTimeoutFilter()if filter ==nil { timeoutCh =nil } else { timeoutCh = time.After(filter.timestamp.Sub(time.Now())) }select {case evnt :=<-watchCh:// new blockchain eventif err := f.dispatchEvent(evnt); err !=nil { f.logger.Error("failed to dispatch event", "err", err) }case<-timeoutCh:// timeout for filterif!f.Uninstall(filter.id) { f.logger.Error("failed to uninstall filter", "id", filter.id) }case<-f.updateCh:// there is a new filter, reset the loop to start the timeout timercase<-f.closeCh:// stop the filter managerreturn } }}