ZChains Whitepaper
  • Overview
  • Tokenomics
    • Glossary
    • Tokenomics
  • Get started
    • Installation
    • Local Setup
    • Cloud Setup
    • CLI Command
  • Additional Features
    • Explorer
    • Network stress testing
  • Architecture
    • Architecture Overview
    • Modules
      • Blockchain
      • Consensus
      • JSON RPC
      • Minimal
      • Networking
      • Other modules
      • Protocol
      • Sealer
      • State
      • Storage
      • TxPool
      • Types
  • Community
    • Propose a new feature
    • Report an issue
  • Concepts
    • State in Ethereum
  • Configuration
    • Manage private keys
    • Server configuration file
    • Secret Managers
      • Set up AWS SSM (Systems Manager)
      • Set up GCP Secrets Manager
      • Set up Hashicorp Vault
  • Consensus
    • Proof of Stake
    • Set up and use Proof of Stake (PoS)
  • Working with node
    • Backup/restore node instance
    • Query JSON RPC endpoints
    • Query operator information
  • Development Roadmap
Powered by GitBook
On this page
  • Overview
  • Blockchain Interface
  • ETH Endpoints
  • Filter Manager
  • 📜 Resources
Export as PDF
  1. Architecture
  2. Modules

JSON RPC

PreviousConsensusNextMinimal

Last updated 10 months ago

Overview

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 , 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 server. It is the base implementation that's passed into the JSON RPC layer.

type blockchainInterface interface {
	// Header returns the current header of the chain (genesis if empty)
	Header() *types.Header

	// GetReceiptsByHash returns the receipts for a hash
	GetReceiptsByHash(hash types.Hash) ([]*types.Receipt, error)

	// Subscribe subscribes for chain head events
	SubscribeEvents() blockchain.Subscription

	// GetHeaderByNumber returns the header by number
	GetHeaderByNumber(block uint64) (*types.Header, bool)

	// GetAvgGasPrice returns the average gas price
	GetAvgGasPrice() *big.Int

	// AddTx adds a new transaction to the tx pool
	AddTx(tx *types.Transaction) error

	// State returns a reference to the state
	State() state.State

	// BeginTxn starts a transition object
	BeginTxn(parentRoot types.Hash, header *types.Header) (*state.Transition, error)

	// GetBlockByHash gets a block using the provided hash
	GetBlockByHash(hash types.Hash, full bool) (*types.Block, bool)

	// ApplyTxn applies a transaction object to the blockchain
	ApplyTxn(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.

type Filter struct {
	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
}


type FilterManager struct {
	logger hclog.Logger

	store   blockchainInterface
	closeCh chan struct{}

	subscription blockchain.Subscription

	filters map[string]*Filter
	lock    sync.Mutex

	updateCh chan struct{}
	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)
	go func() {
		for {
			evnt := f.subscription.GetEvent()
			if evnt == nil {
				return
			}
			watchCh <- evnt
		}
	}()

	var timeoutCh <-chan time.Time
	for {
		// 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 event
			if err := f.dispatchEvent(evnt); err != nil {
				f.logger.Error("failed to dispatch event", "err", err)
			}

		case <-timeoutCh:
			// timeout for filter
			if !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 timer

		case <-f.closeCh:
			// stop the filter manager
			return
		}
	}
}

📜 Resources

The Filter Manager relies heavily on Subscription Events, mentioned in the section

json-rpc endpoints
Minimal
Blockchain
Ethereum JSON-RPC