TrueChain方案设计

in #true6 years ago

TrueChain方案设计
1 Introduction
Truechain是基于go-ethereum源代码实现的基础链,使用与以太坊一致的加密原语。椭圆曲线(secp256k1,ECDSA),哈希(keccak-256),Merkle树。
2 Definitions
账本实现为双链结构(fast chain, snail chain),fast chain块数据由PBFT委员会产生,主要包含了用户的交易及智能合约数据,由PBFT委员会通过共识达成一致。Snail chain块数据为包含了若干个fruit的block,fruit中包含了fast chain的hash及块高度。
Snail chain与fast chain之间的关系,snail chain顺序记录了fast chain的每个数据块的hash和高度,并且也提供了PBFT换届的候选成员及每届委员会的产生数据块的最大数量;fast chain记录了用户的所有交易,提供交易的验证与查询。
所有节点都需要存储fast chain和snail chain的账本数据(有疑问),
-----需要向新连接的节点去同步,同步的过程目前没人做,downloader模块来处理。
一个fruit--包含一个fast chain(FBslock)
新节点加入需要根据snail chain的难度从K(K桶是什么?)桶中计算出最优节点并从该节点同步snail chain数据和fast chain数据,
K桶,在同步的时候用,链接通信,有一个K桶算法,选择有一个最合适的节点。blockchain里面(以太坊)。有一个算法。照着改一下估计就可以了。
然后根据snail chain中记录的fast chain数据的信息来验证fast chain的数据块。(创建一个work的时候需要做这一步,验证,验证什么?)
2.1 Fast block
Fast block is block of the fast chain.
type FastHeader struct {
ParentHash common.Hash json:"parentHash" gencodec:"required"

Root common.Hash json:"stateRoot" gencodec:"required"
---是状态,root可以理解为state 里面存储账户的状态,也是树。
TxHash common.Hash json:"transactionsRoot" gencodec:"required"
ReceiptHash common.Hash json:"receiptsRoot" gencodec:"required"
---默克尔树 收据,每笔交易的哈希。
Bloom Bloom json:"logsBloom" gencodec:"required"
---做block过滤,为了快速检索块。后续为了便于检索。
Number *big.Int json:"number" gencodec:"required"
SnailHash common.Hash
SnailNumber *big.Int
GasLimit uint64 json:"gasLimit" gencodec:"required"
GasUsed uint64 json:"gasUsed" gencodec:"required"
Time *big.Int json:"timestamp" gencodec:"required"
Extra []byte json:"extraData" gencodec:"required"
--目前没有用。保留以太坊里面的,为了扩展用
Hash common.Hash json:"mixHash" gencodec:"required"
}

type FastBody struct {
Transactions []*Transaction
Signs []string
---签名 委员会的加密私钥。所以我们每一个节点都有委员会的公钥。(委员会的密码对)
}
The PBFT committee offer fast blocks to other nodes. The fast block has sequence number and hash to indicate a block. Similar to ethereum block, fast block provides TxHash, Root, ReceiptHash for other nodes to verify transactions included at fast block body.
Field SnailNumber and SnailHash is used when the fast block have the rewards to miner (described in 4.2). When SnailNumber is not equal to 0, it means this fast block has the rewards to the snail block miner and fruits miner.
2.2 Snail Block and Fruit
Truechain uses Fruit Chain as snail chain.
· Fruit is used to stamp fast block.
· Fruit is hanged on snail block.
· When a fruit points to a fast block, the fruit stamps the fast block’s hash and number in it.
· Every fast block has only one fruit to stamp its hash and number.
Referring to the paper, snail block and fruit have the same structure:
type SnailHeader struct {
ParentHash common.Hash json:"parentHash" gencodec:"required"

PointerHash common.Hash json:"pointerHash" gencodec:"required"
--当指向构造的block当被包含---新鲜度的判断。
FruitsHash common.Hash json:"fruitSetHash" gencodec:"required"

FastHash common.Hash json:"fastblockHash" gencodec:"required"
FastNumber *big.Int json:"fashblockNumber" gencodec:"required"
ToElect bool
---这个类似自己在挖矿的时候,表示是否需要参加选举。(需要就要写上下面的publickey)

Coinbase common.Address json:"miner" gencodec:"required"
---矿工 收钱的地址。
Publickey *ecdsa.PublicKey
---矿工的公钥,用于竞选委员
Bloom Bloom json:"logsBloom" gencodec:"required"
Difficulty *big.Int json:"difficulty" gencodec:"required"
Number *big.Int json:"number" gencodec:"required"
Time big.Int json:"timestamp" gencodec:"required"
Extra []byte json:"extraData" gencodec:"required"
MixDigest common.Hash json:"mixHash" gencodec:"required"
--跟nonce配合使用
Nonce BlockNonce json:"nonce" gencodec:"required"
}
type SnailBody struct {
Fruits []
SnailHeader
}
We can use a SnailHeader to indicate a Fruit and fruits will be included in snail block body.
A public key is defined in snail block header, which others can use to verify signatures when this block/fruit miner selected as a committee member.
3 Program Architecture (getrue)
The program is based ethereum program geth, we can call it getrue.
3.1 PBFT protocol
a. 工作流程
· 由leader将本地tx pool当中收到的一组交易打包并签名,将该消息广播出去供其他委员会成员进行投票验证;
· 委员会其他成员收到消息后,对该组交易执行并校验tx hash、state root和receipts root是否正确,如果校验通过则签名并广播出去;
· 当超过2/3的委员签名通过后,该消息构造成fast block并广播出去,同时委员会各成员同步最新状态到该block;
· 然后开始新一个fast block的处理
· 如果leader本地tx pool为空,则leader也需要在等待δ(5秒)时间后生成新的fast block(交易为空)。而此时如果委员会其他成员收到该消息后,若发现自己本地存在可打包交易,则认为此时leader不作为,可不签名该消息并导致view change更换leader。
b. 委员会选举与切换
委员会定期换届,换届周期由snail chain确定,考虑委员会切换的平滑进行,如上图所示:

· 每一届委员会的切换周期为Z个Snail Block,如图第R届委员会的周期为Block N+1到Block N+Z;
· 当挖到Block N+Z时,委员会启动换届,但此时委员会继续工作;
· 获取Block N+Z-λ(考虑到snail chain分叉的问题,因此向前推λ个块)当中包含的最后一个Fruit所指向的Fast Block(FBm),以此为基准,委员会继续工作到生成 FBm+k后,由新的(R+1)届委员会开始工作;
· (R+1)届委员会当收到FBm+k以后启动工作,开始生成FBm+k+1;
· (R+1)届委员会成员从Snail Block N-λ到Block N+Z-λ当中包含的Fruit和Block Miner选举产生,具体选举算法参考文档《BFT委员会选举》;
· 第一届委员会成员在genesis block当中指定;
· 上述参数Z、λ和k可根据实际测试后选定,初始值建议为Z=100,λ=12,k=10000
c. 异常处理
委员会如果工作不正常,需要有机制进行异常处理,这里讨论两种情况:
· 委员会作恶,此时其他节点收到委员会生成的fast block无法验证通过
· 委员会不工作,即长时间无法形成共识输出fast block,此时其他节点会在Δ时间(30秒或者更长)无法收到新的fast block
当节点判断出现以上两种情况时,则在本地启动新的委员会选举,选中的委员会成员开始新的工作。新的委员会的选举算法,可参考上面的选举算法,但是将本届委员会成员剔除。
3.2 fPOW
fPOW的工作流程如下图所示。(只需要sbevnet和fruitevnent就行)
为什么snail是pool而其他的都是队列?答:都是队列。

a. 收到fast block
· 如果该fast block的parent block未收到或者未验证,则将block放入缓存队列,等待后续处理; FB处理。
· 对该fast block进行验证,若验证成功,则在本地已经确认交易完成,将交易信息和状态信息同步到本地数据库中,将该block广播出去,并放入pending队列等待pow流程;FB处理。
· 若该fast block验证失败,则认为委员会作恶,启动委员会重新选举流程,具体描述参见3.1 c部分。
b. 收到fruit
· 验证fruit新鲜度、难度等是否满足要求;
· 该fruit指向的fast block在本地是否已经确认,如果已经确认,则认为该fruit有效,广播fruit,并将fruit放入pending list,等待挖block时放入fruit set;
· 如果该fruit指向的fast block在本地未确认,则放入缓存队列,等待fast block确认后再处理;
· 当收到指向某个fast block的多个fruit时,选择difficulty最大或者整体hash最小的那个fruit。
---现在使用的是选择hash最小(block和fruit一对一,所以需要舍弃其他)。构造block,fruit要顺序排列,不能有缺(就是number要连续)。不能少也不能重复(就是这个block包含的和上下block包含的不能有重复的)。
---挖矿的时候只是拷贝,如果挖成功了,才去删除。构造的时候判断是否重复。
c. 收到新的snail block
· 停止当前挖矿工作
· 将已经包含在block中的fruit和相应fast block从snail pool中移除
如果失败了如何处理?正常应该是创建的时候就会包含FB,然后去删除SBPOOL里面的。
· 广播该block,并更新本地snail chain
· 重新构造新的挖矿任务
· 判断是否需要进行委员会选举,如果需要选举,则根据选举算法计算出新的委员会成员,并判断自己是否属于委员会成员。
d. Mining
· 构建snail block,选择pending list当中最小的一个尚未被生成fruit的fast block,同时将pending list当中所有fruit包含进来
---举例当这次有1-100个fruit以及101还是fb,那这次要把1-101都包含过来,如果只包含1-100那就是挖矿了,难度太大,所以都包含进来进行处理,最后根据输出信息的nonce等判断是fruit还是block。
· 如果挖水果成功,则将该fruit放入pending list并将fruit广播出去
· 如果挖block成功,则将该block广播出去,并更新本地snail chain
4 Incentive
4.1 GAS Fee
GAS费用由委员会成员平分,在每个fast block当中实现分配,即委员会leader构造fast block时,即包含了对于gas费用的分配。
4.2 Mining Reward
对于POW的奖励,分配原则为:
· Block的奖励为初期为60个TRUE,每挖出50000个Snail Block奖励减半;
· Block的奖励由Block矿工与委员会按照比例进行分配,具体分配方式按照黄皮书进行。
· 对于包含在Block当中的Fruit,前期每个Fruit固定奖励0.03个币。
· 对于Block矿工,还有对其包含Fruit的奖励,奖励值为该Block包含的所有Fruit的奖励的10%。
由于所有的state更新均在fast block当中体现,因此对于mining的激励分配也在fast block进行。当snail block N被挖出来时,可对Block N-λ (λ=12)进行激励分配,将要分配激励的snail block的Block Number和Hash记入fast block当中。
--为了要对矿工奖励,给矿工钱,钱的信息,只有FB有state(也就是root字段)状态信息,激励这个块。假如现在到了100的个sb,那可以对第88的个块奖励,把88这个块奖励信息记录到这最新的FB里面去(所以这个新的fb的sbnumber是88)。
5 API与客户端
客户端提供了JSON-RPC和web3j的访问方式,增加少许接口数量,接口名字需要修改,客户端工具暂时使用ethereum-wallet或mist工具。智能合约编辑与编译依然使用原以太坊工具。
6 下一版本需要考虑
6.1 State Snapshot
6.2 VM
6.3 Sharding