angine

package
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Dec 10, 2018 License: LGPL-3.0, Apache-2.0 Imports: 36 Imported by: 0

README

What is angine?

Angine is a completely self-contained blockchain consensus engine. At the core, we use Tendermint BFT. It is an implementation of a Byzantine Fault Tolerant PoS consensus algorithm. So thank you Tendermint team. We just wrap those many things that tendermint already offered together under a concept, "Angine".

Structure of Angine

├── angine.go
├── blockchain
│   ├── pool.go
│   ├── pool_test.go
│   ├── reactor.go
│   └── store.go
├── config
│   ├── config.go
│   └── templates.go
├── consensus
│   ├── byzantine_test.go
│   ├── common.go
│   ├── common_test.go
│   ├── height_vote_set.go
│   ├── height_vote_set_test.go
│   ├── mempool_test.go
│   ├── reactor.go
│   ├── reactor_test.go
│   ├── README.md
│   ├── replay.go
│   ├── replay_test.go
│   ├── state.go
│   ├── state_test.go
│   ├── test_data
│   │   ├── build.sh
│   │   ├── empty_block.cswal
│   │   ├── README.md
│   │   ├── small_block1.cswal
│   │   └── small_block2.cswal
│   ├── ticker.go
│   ├── version.go
│   └── wal.go
├── LICENSE
├── log.go
├── mempool
│   ├── mempool.go
│   ├── mempool_test.go
│   └── reactor.go
├── plugin
│   ├── init.go
│   └── specialop.go
├── README.md
├── refuse_list
│   ├── refuse_list.go
│   └── refuse_list_test.go
├── specialop.go
├── state
│   ├── errors.go
│   ├── execution.go
│   ├── execution_test.go
│   ├── plugin.go
│   ├── state.go
│   ├── state_test.go
│   ├── tps.go
│   └── tps_test.go
├── trace
│   ├── reactor.go
│   └── router.go
└── types
    ├── application.go
    ├── block.go
    ├── block_meta.go
    ├── canonical_json.go
    ├── common.go
    ├── core.go
    ├── events.go
    ├── genesis.go
    ├── hooks.go
    ├── keys.go
    ├── mempool.go
    ├── part_set.go
    ├── part_set_test.go
    ├── priv_validator.go
    ├── proposal.go
    ├── proposal_test.go
    ├── query.go
    ├── resultcode.go
    ├── result.go
    ├── rpc.go
    ├── signable.go
    ├── specialOP.go
    ├── tx.go
    ├── validator.go
    ├── validator_set.go
    ├── validator_set_test.go
    ├── vote.go
    ├── vote_set.go
    ├── vote_set_test.go
    └── vote_test.go

This is directory structure of Angine, you can see that we have packed every module under its own directory. This give you a clear view of the parts making up an Angine.

  1. state/ is the running state of the Angine, which is driven by blockchain/, mempool/ and consensus/
  2. blockchain/ takes charge of syncing blocks, loading blocks, persisting blocks and anything that physically related to "block"
  3. mempool/ takes charge of buffering effective transactions and reaching an agreement about the order of transactions
  4. consensus/ takes charge of gossipping between peers, consensus algorithm related data stream
  5. trace/ is just another reactor module used for specialop votes currently

What we have fulfilled

  1. configurable CA based on asymmetric cyrpto

  2. Dynamically changing ValidatorSet of ConsensusState

  3. Two kinds of transactions, normal and special, are totally isolated. Special tx will only be processed by plugins by default.

  4. Angine plugins

  5. Node joining will automatically download genesisfile from the first seed listed in config file

How to use

Configuration

For angine, every thing angine needs is located at a universal directory, named "angine_runtime". By default, the directory sits at $HOME/.angine. And we also provide an environment variable to override the default: ANGINE_RUNTIME.

The auto generated runtime looks like this:

├── config.toml
├── data
├── genesis.json
└── priv_validator.json
  • config.toml contains all your custom configs for Angine
  • data contains all the data generated when Angine starts running
  • genesis.json defines genesis state of your blockchain
  • priv_validator.json contains your node's private/public key pair

Let me just show you a simplified config.toml:

# This is a TOML config file.
# For more information, see https://github.com/toml-lang/toml

environment = "development"
db_backend = "leveldb"
moniker = "anonymous"
p2p_laddr = "tcp://0.0.0.0:46656"
seeds = ""

# auth by ca general switch
auth_by_ca = true

# whether non-validator nodes need auth by ca, only effective when auth_by_ca is true
non_validator_auth_by_ca = true

# auth signature from CA
signbyCA = ""

fast_sync = true

skip_upnp = true

log_path = ""

#log_level:
        # -1 DebugLevel logs are typically voluminous, and are usually disabled in production.
        #  0 InfoLevel is the default logging priority.
        #  1 WarnLevel logs are more important than Info, but don't need individual human review.
        #  2 ErrorLevel logs are high-priority. If an application is running smoothly, it shouldn't generate any error-level logs.
        #  3 DPanicLevel logs are particularly important errors. In development the logger panics after writing the message.
        #  4 PanicLevel logs a message, then panics.
        #  5 FatalLevel logs a message, then calls os.Exit(1)
Default CA signature

Suppose you want to join a chain with a public key "123456" and its chainID is "abc". The patten is like $publickey$$chainID$:

123456abc

This message above is what you should give the CA node of that chain and expect a corresponding signature which means an authorized identity to join.

Further more, a blockchain can choose to use 3 different auth strategies:

  • auth by default
  • only validators need auth
  • no auth at all
Initialize Angine

This is how you initialize an angine.

angine.Initialize(&angine.Tunes{Conf: conf})

The "angine.Initialize" will handle the generation of default configs, genesis file and private key. You must only do this once for a particular chain, otherwise, your chain id will be different for sure.

Construct a Tunes.
type Tunes struct {
    Runtime string
    Conf    *viper.Viper
}

This struct contains 2 fields and you only have to fill one:

  1. Runtime is a path that contains all the auto-generated files. So provided this will just generate everything under this path with random chainID and private/pub key pair.

  2. Conf contains any config that you want to override the defaults. Say, you wanna use some cli args to override the default configs, this is the thing you should look into.

    After, you probably need to edit those files mannually to get exactly what you want. Everything in the files are straigt forward.

New an Angine instance and start it

First, you need to import angine into your project :-) then,

// this line should be changed to github path accordingly
import "github.com/dappledger/AnnChain/angine" 

...

mainAngine := angine.NewAngine(&angine.Tunes{Conf: conf})

...

mainAngine.Start()

That is all.

Manage Validator Set

Angine is designed to be capable of chaning validators dynamically.

First of all, all new connected nodes are by default non-validator. If the node wants to become a validator, a change_validator command is required. In angine world, such a command is called special operation and change_validator must come from CA node.

Suppose you are a CA node, use the following command to initiate a special operation to change a normal node into a validator:

anntool --backend=${CA's RPC address} --target="${chainid}" special change_validator --privkey="${CA's privatekey}" --power=${voting power} --isCA="{false/true}" --validator_pubkey="${the node's publickey}"

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func CheckSpecialOPVoteSig

func CheckSpecialOPVoteSig(cmd *types.SpecialOPCmd, pk crypto.PubKey, sigData []byte) error

CheckSpecialOPVoteSig just wraps the action on how to check the votes we got.

func GenChainid

func GenChainid() string

func Initialize

func Initialize(tune *Tunes, chainId string)

Initialize generates genesis.json and priv_validator.json automatically. It is usually used with commands like "init" before user put the node into running.

func InitializeLog

func InitializeLog(env, logpath string) *zap.Logger

func ProtocolAndAddress

func ProtocolAndAddress(listenAddr string) (string, string)

ProtocolAndAddress accepts tcp by default

Types

type Angine

type Angine struct {
	Tune *Tunes
	// contains filtered or unexported fields
}

Angine is a high level abstraction of all the state, consensus, mempool blah blah...

func NewAngine

func NewAngine(lgr *zap.Logger, tune *Tunes) (angine *Angine)

NewAngine makes and returns a new angine, which can be used directly after being imported

func (*Angine) AppendSignatureToSpecialCmd

func (e *Angine) AppendSignatureToSpecialCmd(cmd *types.SpecialOPCmd, pubkey crypto.PubKey, sig crypto.Signature)

AppendSignatureToSpecialCmd appends signature onto cmd.Sigs

func (*Angine) BeginBlock

func (ang *Angine) BeginBlock(block *agtypes.BlockCache, eventFireable events.Fireable, blockPartsHeader *pbtypes.PartSetHeader)

func (*Angine) BroadcastTx

func (ang *Angine) BroadcastTx(tx []byte) error

func (*Angine) BroadcastTxCommit

func (ang *Angine) BroadcastTxCommit(tx []byte) error

func (*Angine) CollectSpecialVotes

func (e *Angine) CollectSpecialVotes(cmd *types.SpecialOPCmd) error

CollectSpecialVotes collects special votes. Communications are made on p2p port by a dedicated reactor. Within tracerouter_msg_ttl timeout, see if we can get more than 2/3 voting power.

func (*Angine) ConnectApp

func (ang *Angine) ConnectApp(app agtypes.Application) error

func (*Angine) Destroy

func (ang *Angine) Destroy()

Destroy is called after something go south while before angine.Start has been called

func (*Angine) DialSeeds

func (ang *Angine) DialSeeds(seeds []string) error

func (*Angine) EndBlock

func (ang *Angine) EndBlock(block *agtypes.BlockCache, eventFireable events.Fireable, blockPartsHeader *pbtypes.PartSetHeader, changedValAttrs []*agtypes.ValidatorAttr, nextVS *agtypes.ValidatorSet)

plugins modify changedValidators inplace

func (*Angine) ExecBlock

func (ang *Angine) ExecBlock(block *agtypes.BlockCache, eventFireable events.Fireable, executeResult *agtypes.ExecuteResult)

func (*Angine) FlushMempool

func (ang *Angine) FlushMempool()

func (*Angine) Genesis

func (ang *Angine) Genesis() *agtypes.GenesisDoc

func (*Angine) GetBlacklist

func (ang *Angine) GetBlacklist() []string

func (*Angine) GetBlock

func (ang *Angine) GetBlock(height def.INT) (block *agtypes.BlockCache, meta *pbtypes.BlockMeta, err error)

func (*Angine) GetBlockMeta

func (ang *Angine) GetBlockMeta(height def.INT) (meta *pbtypes.BlockMeta, err error)

func (*Angine) GetConsensusStateInfo

func (ang *Angine) GetConsensusStateInfo() (string, []string)

func (*Angine) GetNodeInfo

func (ang *Angine) GetNodeInfo() *p2p.NodeInfo

func (*Angine) GetNonEmptyBlockIterator

func (ang *Angine) GetNonEmptyBlockIterator() *blockchain.NonEmptyBlockIterator

func (*Angine) GetNumPeers

func (ang *Angine) GetNumPeers() int

func (*Angine) GetNumUnconfirmedTxs

func (ang *Angine) GetNumUnconfirmedTxs() int

func (*Angine) GetP2PNetInfo

func (ang *Angine) GetP2PNetInfo() (bool, []string, []*agtypes.Peer)

func (*Angine) GetUnconfirmedTxs

func (ang *Angine) GetUnconfirmedTxs() []agtypes.Tx

func (*Angine) GetValidators

func (ang *Angine) GetValidators() (def.INT, *agtypes.ValidatorSet)

func (*Angine) Height

func (ang *Angine) Height() def.INT

func (*Angine) InitPlugins

func (ang *Angine) InitPlugins()

func (*Angine) IsNodeValidator

func (ang *Angine) IsNodeValidator(pub crypto.PubKey) bool

func (*Angine) NonEmptyHeight

func (ang *Angine) NonEmptyHeight() def.INT

func (*Angine) OriginHeight

func (ang *Angine) OriginHeight() def.INT

func (*Angine) P2PHost

func (ang *Angine) P2PHost() string

func (*Angine) P2PPort

func (ang *Angine) P2PPort() uint16

func (*Angine) PrivValidator

func (ang *Angine) PrivValidator() *agtypes.PrivValidator

func (*Angine) ProcessSpecialOP

func (e *Angine) ProcessSpecialOP(tx []byte) error

ProcessSpecialOP is the ability of Angine. It is called when a specialop tx comes in but before going into mempool. We do a specialvotes collection here. Only with 2/3+ voting power can the tx go into mempool.

func (*Angine) ProcessVoteChannel

func (e *Angine) ProcessVoteChannel(tx atypes.Tx) (*atypes.ResultRequestVoteChannel, error)

RequestVoteChannel handle user rpc requst

func (*Angine) Query

func (ang *Angine) Query(queryType byte, load []byte) (interface{}, error)

func (*Angine) RecoverFromCrash

func (ang *Angine) RecoverFromCrash(appHash []byte, appBlockHeight def.INT) error

Recover world status Replay all blocks after blockHeight and ensure the result matches the current state.

func (*Angine) RegisterNodeInfo

func (ang *Angine) RegisterNodeInfo(ni *p2p.NodeInfo)

func (*Angine) SignSpecialOP

func (e *Angine) SignSpecialOP(cmd *types.SpecialOPCmd) ([]byte, error)

SignSpecialOP wraps around plugin.Specialop

func (*Angine) SpecialOPResponseHandler

func (e *Angine) SpecialOPResponseHandler(data []byte) []byte

SpecialOPResponseHandler defines what we do when we get a specialop request from a peer. This is mainly used as a callback within TraceRouter.

func (*Angine) Start

func (ang *Angine) Start() (err error)

func (*Angine) Stop

func (ang *Angine) Stop() bool

Stop just wrap around swtich.Stop, which will stop reactors, listeners,etc

type ITxCheck

type ITxCheck interface {
	CheckTx(agtypes.Tx) (bool, error)
}

type MempoolFilter

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

func NewMempoolFilter

func NewMempoolFilter(f func([]byte) (bool, error)) MempoolFilter

func (MempoolFilter) CheckTx

func (m MempoolFilter) CheckTx(tx agtypes.Tx) (bool, error)

type MockMempool

type MockMempool struct {
}

Updates to the mempool need to be synchronized with committing a block so apps can reset their transient state on Commit

func (MockMempool) Lock

func (m MockMempool) Lock()

func (MockMempool) Unlock

func (m MockMempool) Unlock()

func (MockMempool) Update

func (m MockMempool) Update(height int64, txs []agtypes.Tx)

type Tunes

type Tunes struct {
	Runtime string
	Conf    *viper.Viper
}

Directories

Path Synopsis
blockchain
Package blockchain is a generated protocol buffer package.
Package blockchain is a generated protocol buffer package.
consensus
Package consensus is a generated protocol buffer package.
Package consensus is a generated protocol buffer package.
events
Package events is a generated protocol buffer package.
Package events is a generated protocol buffer package.
mempool
Package mempool is a generated protocol buffer package.
Package mempool is a generated protocol buffer package.
rpc
Package rpc is a generated protocol buffer package.
Package rpc is a generated protocol buffer package.
state
Package state is a generated protocol buffer package.
Package state is a generated protocol buffer package.
trace
Package trace is a generated protocol buffer package.
Package trace is a generated protocol buffer package.
types
Package types is a generated protocol buffer package.
Package types is a generated protocol buffer package.
utils
zip

Jump to

Keyboard shortcuts

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