There are two app's here: the KVStoreApplication and the PersistentKVStoreApplication.


The KVStoreApplication is a simple merkle key-value store. Transactions of the form key=value are stored as key-value pairs in the tree. Transactions without an = sign set the value to the key. The app has no replay protection (other than what the mempool provides).


The PersistentKVStoreApplication wraps the KVStoreApplication and provides two additional features:

  1. persistence of state across app restarts (using Tendermint's ABCI-Handshake mechanism)
  2. validator set changes

The state is persisted in leveldb along with the last block committed, and the Handshake allows any necessary blocks to be replayed. Validator set changes are effected using the following transaction format:


where pubkeyN is a base64-encoded 32-byte ed25519 key and powerN is a new voting power for the validator with pubkeyN (possibly a new one). To remove a validator from the validator set, set power to 0. There is no sybil protection against new validators joining.

Expand ▾ Collapse ▴




View Source
const (
	ValidatorSetChangePrefix string = "val:"


View Source
var (
	ProtocolVersion uint64 = 0x1


func InitKVStore

func InitKVStore(app *PersistentKVStoreApplication)

    InitKVStore initializes the kvstore app with some data, which allows tests to pass and is fine as long as you don't make any tx that modify the validator state

    func MakeValSetChangeTx

    func MakeValSetChangeTx(pubkey pc.PublicKey, power int64) []byte

    func RandVal

    func RandVal(i int) types.ValidatorUpdate

      RandVal creates one random validator, with a key derived from the input value

      func RandVals

      func RandVals(cnt int) []types.ValidatorUpdate

        RandVals returns a list of cnt validators for initializing the application. Note that the keys are deterministically derived from the index in the array, while the power is random (Change this if not desired)


        type Application

        type Application struct {
        	RetainBlocks int64 // blocks to retain after commit (via ResponseCommit.RetainHeight)
        	// contains filtered or unexported fields

        func NewApplication

        func NewApplication() *Application

        func (*Application) CheckTx

        func (*Application) Commit

        func (app *Application) Commit() types.ResponseCommit

        func (*Application) DeliverTx

          tx is either "key=value" or just arbitrary bytes

          func (*Application) Info

          func (app *Application) Info(req types.RequestInfo) (resInfo types.ResponseInfo)

          func (*Application) Query

          func (app *Application) Query(reqQuery types.RequestQuery) (resQuery types.ResponseQuery)

            Returns an associated value or nil if missing.

            type PersistentKVStoreApplication

            type PersistentKVStoreApplication struct {
            	// validator set
            	ValUpdates []types.ValidatorUpdate
            	// contains filtered or unexported fields

            func NewPersistentKVStoreApplication

            func NewPersistentKVStoreApplication(dbDir string) *PersistentKVStoreApplication

            func (*PersistentKVStoreApplication) ApplySnapshotChunk

            func (*PersistentKVStoreApplication) BeginBlock

              Track the block hash and header information

              func (*PersistentKVStoreApplication) CheckTx

              func (*PersistentKVStoreApplication) Commit

                Commit will panic if InitChain was not called

                func (*PersistentKVStoreApplication) DeliverTx

                  tx is either "val:pubkey!power" or "key=value" or just arbitrary bytes

                  func (*PersistentKVStoreApplication) EndBlock

                    Update the validator set

                    func (*PersistentKVStoreApplication) Info

                    func (*PersistentKVStoreApplication) InitChain

                      Save the validators in the merkle tree

                      func (*PersistentKVStoreApplication) ListSnapshots

                      func (*PersistentKVStoreApplication) LoadSnapshotChunk

                      func (*PersistentKVStoreApplication) OfferSnapshot

                      func (*PersistentKVStoreApplication) Query

                      func (app *PersistentKVStoreApplication) Query(reqQuery types.RequestQuery) (resQuery types.ResponseQuery)

                        When path=/val and data={validator address}, returns the validator update (types.ValidatorUpdate) varint encoded. For any other path, returns an associated value or nil if missing.

                        func (*PersistentKVStoreApplication) SetLogger

                        func (app *PersistentKVStoreApplication) SetLogger(l log.Logger)

                        func (*PersistentKVStoreApplication) SetOption

                        func (*PersistentKVStoreApplication) Validators

                        func (app *PersistentKVStoreApplication) Validators() (validators []types.ValidatorUpdate)

                        type State

                        type State struct {
                        	Size    int64  `json:"size"`
                        	Height  int64  `json:"height"`
                        	AppHash []byte `json:"app_hash"`
                        	// contains filtered or unexported fields