12.14 普通节点问题push汇总 - Agzs/geth-pbft-study GitHub Wiki
普通节点问题
本次push主要解决了普通节点的适用问题,即普通节点和pbft的共识节点使用同一套系统,而普通节点不需要rocksDB数据库,也不需要pbft共识,只是进行交易和同步区块。
1. cmd/geth/main.go
在init()函数中为viper增加config.yaml的新路经为”$HOME/.geth-pbft",相关操作如下:
// Path to look for the config file in based on HOME
home := os.Getenv("HOME") //=>GOPATH -> HOME --Agzs
for _, p := range filepath.SplitList(home) {
pbftpath := filepath.Join(p, ".geth-pbft") //=>11.13 path--Agzs
viper.AddConfigPath(pbftpath)
}
2. consensus/pbft/api.go
在Propose()和Discard()函数中追加条件,即这两个函数仅限pbft共识的节点调用,普通节点调用不起作用,如下:
func (api *API) Propose(address common.Address, auth bool) {
if api.pbft.GetID() == DefaultPbftID { //=>add for ordinary node --Agzs 12.13
log.Warn("Sorry, you are not VP, can't do this!!!")
return
}
api.pbft.lock.Lock()
defer api.pbft.lock.Unlock()
api.pbft.proposals[address] = auth
}
其中DefaultPbftID为默认的pbftID,在geth指令中缺省--pbftid X时起作用,效果如下:
> pbft.propose("0x079aafa464a201cf265850d852457812766bf549",true)
WARN [12-15|08:43:18] Sorry, you are not VP, can't do this!!!
null
>
> pbft.propose("0x079aafa464a201cf265850d852457812766bf549",false)
WARN [12-15|08:43:29] Sorry, you are not VP, can't do this!!!
null
>
> pbft.discard("0x079aafa464a201cf265850d852457812766bf549")
WARN [12-15|08:44:39] Sorry, you are not VP, can't do this!!!
null
>
3. consensus/pbft/pbft.go
- 添加全局变量,用于在geth指令中缺省
--pbftid X时,为普通用户指定无效的pbftID
const DefaultPbftID = 1000 //=> set DefaultPbftID to 1000
该变量在多处被调用,主要用于判断当前运行的节点是否为普通节点
- 在
func New(id uint64, config *params.PBFTConfig, db ethdb.Database) *PBFT{}中添加普通节点操作,即普通节点不需要初始化pbftCore实例和其相关的其他操作。
func New(id uint64, config *params.PBFTConfig, db ethdb.Database) *PBFT{
....
if pb.config.Epoch == 0 {
pb.config.Epoch = epochLength
}
if pb.config.Period == 0 {
pb.config.Period = blockPeriod
}
if pb.id == DefaultPbftID { //=> add for ordinary node. --Agzs 12.13
return pb
}
pb.manager.SetReceiver(pb) /// Need to implement ProcessEvent. --Zhiguo
etf := events.NewTimerFactoryImpl(pb.manager)
....
}
-
凡涉及
c.pbft.XXXX均需要在其前添加是否为普通节点的判断,原因是普通节点不需要初始化pbftCore实例,如果不添加判断的话,会导致空指针错误 -
修改
seal()函数中的条件,使普通节点在pbft共识中无法进行挖矿
> miner.start()
INFO [12-15|08:44:52] Transaction pool price threshold updated price=18000000000
INFO [12-15|08:44:52] Starting mining operation
null
> INFO [12-15|08:44:52] Commit new mining work number=20 txs=0 uncles=0 elapsed=107.142µs
WARN [12-15|08:44:52] Block sealing failed err="not signer(primary and backup), cannot issue Seal"
- 为
config.yaml文件追加公共路径“HOME/.geth-pbft`,用于配置文件的查找
4. core/db/db.go
添加全局变量RunningFlag,用于标记rocksDB是否启动,用于后期数据库的关闭
5. eth/backend.go
在func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) {}函数中,添加普通节点的判断,普通节点不会启动rocksDB数据库,只有pbft共识的节点才会启动rocksDB数据库;相应地,只有rocksDB数据库处于开启状态(RunningFlag == true,结束时才能关闭数据库
6. config.go
将DefaultConfig中的PbftId由 0 修改为DefaultPbftID,用于区别普通节点和共识节点
7. handler.go
-
在
NewProtocolManager()中的PBFT分支中添加普通节点判断,普通节点不用设置commChan和manager -
在
func (pm *ProtocolManager) handle(p *peer) error {}节点成功连接后,追加普通节点广播自身enode操作,用于普通节点间的两两互连