nullchain

package
v0.0.0-...-589da53 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 30, 2023 License: MIT Imports: 30 Imported by: 0

README

Null-Blockchain

The Null-Blockchain is considered an alternative chain-provider for core that acts like a dummy tendermint. The idea is that by removing all the config and setup needed for tendermint, a single fury node can be started on its own that can process transactions and create blocks without needing to provide any consensus. Block-time is also frozen until enough transactions fill a block, or a call to a "backdoor" API is used to move time time forward. The aim is that this can be used as an internal tool to run simulations and aid testing.

Using the Null-blockchain

Providing the following options when running fury node, or by setting them in config.toml will start fury with a null-blockchain:

--blockchain.chain-provider=nullchain
--blockchain.nullchain.log-level=debug
--blockchain.nullchain.transactions-per-block=10
--blockchain.nullchain.block-duration=1s
--blockchain.nullchain.genesis-file=PATH_TO_TM_GENESIS_FILE

PATH_TO_TM_GENESIS_FILE is required and can be a normal genesis.json that would be used with Tendermint. The Null-blockchain requires it to be able to parse and send the app_state to InitChain. Also if genesis_time is set it will be used as the initial frozen time of the chain, otherwise it will be set to time.Now().

Moving Time Forward

There are two ways in which time can be moved forward. The first is by submitting a number of transactions equal to transactions-per-block. Once this threshold is hit the submitted transactions will be processed, and furytime will be incremented by block-duration.

The other is by using an exposed HTTP endpoint to specify either a duration, or a future datetime:

# By duration
curl -X POST -d "{\"forward\": \"10s\"}" http://localhost:3101/api/v1/forwardtime


# By datetime
curl -X POST -d "{\"forward\": \"2021-11-25T14:14:00Z\"}" http://localhost:3101/api/v1/forwardtime

Moving time forward will create empty blocks until the target time is reached. Any pending transactions will be processed in the first block. If the target time is such that it does not move ahead by a multiple of block-duration then time will be snapped backwards to the block last ended, and furytime could be less than the target time.

Depositing Funds and Staking

The Null-Blockchain is made to work with as few external dependencies as possible and so does not dial into the Ethereum chain. This means that all assets being used must be built-in assets, and not ERC20. Funds can be deposited into the system using the faucet (See fury faucet --help).

To be able to be able to flex goverance the null-blockchain will need to be able to pretend that a party has staked to allow voting and proposals to work. This is done with a mock up a staking account that loops itself into the collateral engine. To be able to simulate staking the faucet can be used to deposit the built-in asset VOTE into a party's general account in the collateral engine. This general account balance for VOTE is then sneakily looped into governance as if it were a staked balance.

Replaying the chain and restoring from a snapshot

The Null-Blockchain contains functionality that allows saving to a file all the per-block-transactions in a way that it can be replayed. The following options control this behaviour:

--blockchain.nullchain.replay-file=SOME_PATH/replay-file
--blockchain.nullchain.replay
--blockchain.nullchain.record

where --blockchain.nullchain.record will turn on writing transaction data into SOME_PATH/replay-file, and --blockchain.nullchain.replay will turn on replaying the chain from that file.

The Null-Blockchain also supports loading from a snapshot. This means that with replay turned on, a stopped chain that is restarted can quickly return to its previous state in exactly the same way as a chain using Tendermint and the blockchain provider.

Documentation

Index

Constants

View Source
const (
	NullChainStatusReady     = "chain-ready"
	NullChainStatusReplaying = "chain-replaying"
)

Variables

View Source
var (
	ErrNotImplemented      = errors.New("not implemented for nullblockchain")
	ErrChainReplaying      = errors.New("nullblockchain is replaying")
	ErrGenesisFileRequired = errors.New("--blockchain.nullchain.genesis-file is required")
)
View Source
var ErrInvalidRequest = errors.New("invalid request")
View Source
var ErrReplayFileIsRequired = errors.New("replay-file is required when replay/record is enabled")

Functions

func RequestToDuration

func RequestToDuration(req string, now time.Time) (time.Duration, error)

RequestToDuration should receive either be a parsable duration or a RFC3339 datetime.

Types

type ApplicationService

type ApplicationService interface {
	InitChain(res abci.RequestInitChain) (resp abci.ResponseInitChain)
	BeginBlock(req abci.RequestBeginBlock) (resp abci.ResponseBeginBlock)
	EndBlock(req abci.RequestEndBlock) (resp abci.ResponseEndBlock)
	Commit() (resp abci.ResponseCommit)
	DeliverTx(req abci.RequestDeliverTx) (resp abci.ResponseDeliverTx)
	Info(req abci.RequestInfo) (resp abci.ResponseInfo)
}

type Assets

type Assets interface {
	Get(assetID string) (*assets.Asset, error)
}

type Collateral

type Collateral interface {
	GetPartyGeneralAccount(party, asset string) (*types.Account, error)
}

type NullBlockchain

type NullBlockchain struct {
	// contains filtered or unexported fields
}

func NewClient

func NewClient(
	log *logging.Logger,
	cfg blockchain.NullChainConfig,
	timeService TimeService,
) *NullBlockchain

func (*NullBlockchain) BeginBlock

func (n *NullBlockchain) BeginBlock() *NullBlockchain

func (*NullBlockchain) CheckTransaction

func (n *NullBlockchain) CheckTransaction(ctx context.Context, tx []byte) (*tmctypes.ResultCheckTx, error)

func (*NullBlockchain) EndBlock

func (n *NullBlockchain) EndBlock() *NullBlockchain

func (*NullBlockchain) ForwardTime

func (n *NullBlockchain) ForwardTime(d time.Duration)

ForwardTime moves the chain time forward by the given duration, delivering any pending transaction and creating any extra empty blocks if time is stepped forward by more than a block duration.

func (*NullBlockchain) GenesisValidators

func (n *NullBlockchain) GenesisValidators(_ context.Context) ([]*tmtypes.Validator, error)

func (*NullBlockchain) GetChainID

func (n *NullBlockchain) GetChainID(context.Context) (string, error)

func (*NullBlockchain) GetGenesisTime

func (n *NullBlockchain) GetGenesisTime(context.Context) (time.Time, error)

func (*NullBlockchain) GetNetworkInfo

func (n *NullBlockchain) GetNetworkInfo(context.Context) (*tmctypes.ResultNetInfo, error)

func (*NullBlockchain) GetStatus

func (*NullBlockchain) GetUnconfirmedTxCount

func (n *NullBlockchain) GetUnconfirmedTxCount(context.Context) (int, error)

func (*NullBlockchain) Health

func (*NullBlockchain) InitChain

func (n *NullBlockchain) InitChain() error

InitChain processes the given genesis file setting the chain's time, and passing the appstate through to the processors InitChain.

func (*NullBlockchain) ReloadConf

func (n *NullBlockchain) ReloadConf(cfg blockchain.Config)

ReloadConf update the internal configuration.

func (*NullBlockchain) SendTransactionAsync

func (n *NullBlockchain) SendTransactionAsync(ctx context.Context, tx []byte) (*tmctypes.ResultBroadcastTx, error)

func (*NullBlockchain) SendTransactionCommit

func (n *NullBlockchain) SendTransactionCommit(ctx context.Context, tx []byte) (*tmctypes.ResultBroadcastTxCommit, error)

func (*NullBlockchain) SendTransactionSync

func (n *NullBlockchain) SendTransactionSync(ctx context.Context, tx []byte) (*tmctypes.ResultBroadcastTx, error)

func (*NullBlockchain) SetABCIApp

func (n *NullBlockchain) SetABCIApp(app ApplicationService)

func (*NullBlockchain) Start

func (n *NullBlockchain) Start() error

func (*NullBlockchain) StartChain

func (n *NullBlockchain) StartChain() error

func (*NullBlockchain) StartServer

func (n *NullBlockchain) StartServer() error

func (*NullBlockchain) Stop

func (n *NullBlockchain) Stop() error

func (*NullBlockchain) Subscribe

func (*NullBlockchain) Validators

func (n *NullBlockchain) Validators(_ context.Context, _ *int64) ([]*tmtypes.Validator, error)

type Replayer

type Replayer struct {
	// contains filtered or unexported fields
}

func NewNullChainReplayer

func NewNullChainReplayer(app ApplicationService, cfg blockchain.ReplayConfig, log *logging.Logger) (*Replayer, error)

func (*Replayer) InitChain

func (r *Replayer) InitChain(req abci.RequestInitChain) (resp abci.ResponseInitChain)

func (*Replayer) Stop

func (r *Replayer) Stop() error

type StakingLoop

type StakingLoop struct {
	// contains filtered or unexported fields
}

func NewStakingLoop

func NewStakingLoop(col Collateral, assets Assets) *StakingLoop

NewStakingLoop return a type that can "mock" a StakingAccount by instead reading deposited amounts from the collateral engine. Used by the null-blockchain to remove the need for an Ethereum connection.

func (*StakingLoop) GetAvailableBalance

func (s *StakingLoop) GetAvailableBalance(party string) (*num.Uint, error)

func (*StakingLoop) GetAvailableBalanceInRange

func (s *StakingLoop) GetAvailableBalanceInRange(party string, from, to time.Time) (*num.Uint, error)

func (*StakingLoop) GetStakingAssetTotalSupply

func (s *StakingLoop) GetStakingAssetTotalSupply() *num.Uint

type TimeService

type TimeService interface {
	GetTimeNow() time.Time
}

Directories

Path Synopsis
Package mocks is a generated GoMock package.
Package mocks is a generated GoMock package.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL