Commit 1d956b38 authored by kingwang's avatar kingwang Committed by 33cn

update chain33 03-20

parent 5dac10d3
...@@ -41,7 +41,7 @@ type DB struct { ...@@ -41,7 +41,7 @@ type DB struct {
// NewCoinsAccount 新建账户 // NewCoinsAccount 新建账户
func NewCoinsAccount() *DB { func NewCoinsAccount() *DB {
prefix := "mavl-coins-bty-" prefix := "mavl-coins-" + types.GetCoinSymbol() + "-"
return newAccountDB(prefix) return newAccountDB(prefix)
} }
......
...@@ -47,7 +47,7 @@ func GetLocalDBKeyList() [][]byte { ...@@ -47,7 +47,7 @@ func GetLocalDBKeyList() [][]byte {
return [][]byte{ return [][]byte{
blockLastHeight, bodyPerfix, LastSequence, headerPerfix, heightToHeaderPerfix, blockLastHeight, bodyPerfix, LastSequence, headerPerfix, heightToHeaderPerfix,
hashPerfix, tdPerfix, heightToHashKeyPerfix, seqToHashKey, HashToSeqPerfix, hashPerfix, tdPerfix, heightToHashKeyPerfix, seqToHashKey, HashToSeqPerfix,
seqCBPrefix, seqCBLastNumPrefix, seqCBPrefix, seqCBLastNumPrefix, tempBlockKey, lastTempBlockKey,
} }
} }
...@@ -156,11 +156,12 @@ func NewBlockStore(db dbm.DB, client queue.Client) *BlockStore { ...@@ -156,11 +156,12 @@ func NewBlockStore(db dbm.DB, client queue.Client) *BlockStore {
//如果没有,那么进行下面的步骤 //如果没有,那么进行下面的步骤
//1. 先把hash 都给改成 TX:hash //1. 先把hash 都给改成 TX:hash
//2. 把所有的 Tx:hash 都加一个 8字节的index //2. 把所有的 Tx:hash 都加一个 8字节的index
//3. 10000个区块 处理一次,并且打印进度 //3. 2000个交易处理一次,并且打印进度
//4. 全部处理完成了,添加quickIndex 的标记 //4. 全部处理完成了,添加quickIndex 的标记
func (bs *BlockStore) initQuickIndex(height int64) { func (bs *BlockStore) initQuickIndex(height int64) {
batch := bs.db.NewBatch(true) batch := bs.db.NewBatch(true)
var count int var maxsize = 100 * 1024 * 1024
var count = 0
for i := int64(0); i <= height; i++ { for i := int64(0); i <= height; i++ {
blockdetail, err := bs.LoadBlockByHeight(i) blockdetail, err := bs.LoadBlockByHeight(i)
if err != nil { if err != nil {
...@@ -172,17 +173,17 @@ func (bs *BlockStore) initQuickIndex(height int64) { ...@@ -172,17 +173,17 @@ func (bs *BlockStore) initQuickIndex(height int64) {
if err != nil { if err != nil {
panic(err) panic(err)
} }
count++ count += len(txresult)
batch.Set(types.CalcTxKey(hash), txresult) batch.Set(types.CalcTxKey(hash), txresult)
batch.Set(types.CalcTxShortKey(hash), []byte("1")) batch.Set(types.CalcTxShortKey(hash), []byte("1"))
} }
if count > 100000 { if count > maxsize {
storeLog.Info("initQuickIndex", "height", i) storeLog.Info("initQuickIndex", "height", i)
err := batch.Write() err := batch.Write()
if err != nil { if err != nil {
panic(err) panic(err)
} }
batch = bs.db.NewBatch(true) batch.Reset()
count = 0 count = 0
} }
} }
...@@ -192,6 +193,7 @@ func (bs *BlockStore) initQuickIndex(height int64) { ...@@ -192,6 +193,7 @@ func (bs *BlockStore) initQuickIndex(height int64) {
panic(err) panic(err)
} }
storeLog.Info("initQuickIndex", "height", height) storeLog.Info("initQuickIndex", "height", height)
batch.Reset()
} }
bs.saveQuickIndexFlag() bs.saveQuickIndexFlag()
} }
......
...@@ -42,13 +42,6 @@ var ( ...@@ -42,13 +42,6 @@ var (
synlog = chainlog.New("submodule", "syn") synlog = chainlog.New("submodule", "syn")
) )
//ForkInfo blockchain模块fork处理结构体
type ForkInfo struct {
ForkStartHeight int64
ForkEndHeight int64
ForkPid string
}
//PeerInfo blockchain模块需要保存的peerinfo //PeerInfo blockchain模块需要保存的peerinfo
type PeerInfo struct { type PeerInfo struct {
Name string Name string
...@@ -128,6 +121,9 @@ func (chain *BlockChain) SynRoutine() { ...@@ -128,6 +121,9 @@ func (chain *BlockChain) SynRoutine() {
//2分钟尝试检测一次最优链,确保本节点在最优链 //2分钟尝试检测一次最优链,确保本节点在最优链
checkBestChainTicker := time.NewTicker(120 * time.Second) checkBestChainTicker := time.NewTicker(120 * time.Second)
//节点启动后首先尝试开启快速下载模式
chain.tickerwg.Add(1)
go chain.FastDownLoadBlocks()
for { for {
select { select {
case <-chain.quit: case <-chain.quit:
...@@ -135,9 +131,9 @@ func (chain *BlockChain) SynRoutine() { ...@@ -135,9 +131,9 @@ func (chain *BlockChain) SynRoutine() {
return return
case <-blockSynTicker.C: case <-blockSynTicker.C:
//synlog.Info("blockSynTicker") //synlog.Info("blockSynTicker")
//SynBlocksFromPeers在task任务中也会go线程调用 if !GetDownloadSyncStatus() {
//WaitGroup不太好处理,暂时不加入WaitGroup中 go chain.SynBlocksFromPeers()
go chain.SynBlocksFromPeers() }
case <-fetchPeerListTicker.C: case <-fetchPeerListTicker.C:
//synlog.Info("blockUpdateTicker") //synlog.Info("blockUpdateTicker")
...@@ -207,15 +203,19 @@ func (chain *BlockChain) FetchBlock(start int64, end int64, pid []string, syncOr ...@@ -207,15 +203,19 @@ func (chain *BlockChain) FetchBlock(start int64, end int64, pid []string, syncOr
var cb func() var cb func()
if syncOrfork { if syncOrfork {
//还有区块需要请求,挂接钩子回调函数 //还有区块需要请求,挂接钩子回调函数
if requestblock.End < chain.forkInfo.ForkEndHeight { if requestblock.End < chain.downLoadInfo.EndHeight {
cb = func() { cb = func() {
chain.ReqForkBlocks() chain.ReqDownLoadBlocks()
} }
chain.UpdateForkStartHeight(requestblock.End + 1) chain.UpdateDownLoadStartHeight(requestblock.End + 1)
} else { // 所有fork block已请求结束,恢复forkinfo为默认值 //快速下载时需要及时更新bestpeer,防止下载侧链的block
chain.DefaultForkInfo() if GetDownloadSyncStatus() {
chain.UpdateDownLoadPids()
}
} else { // 所有DownLoad block已请求结束,恢复DownLoadInfo为默认值
chain.DefaultDownLoadInfo()
} }
err = chain.forktask.Start(requestblock.Start, requestblock.End, cb) err = chain.downLoadTask.Start(requestblock.Start, requestblock.End, cb)
if err != nil { if err != nil {
return err return err
} }
...@@ -225,13 +225,13 @@ func (chain *BlockChain) FetchBlock(start int64, end int64, pid []string, syncOr ...@@ -225,13 +225,13 @@ func (chain *BlockChain) FetchBlock(start int64, end int64, pid []string, syncOr
chain.SynBlocksFromPeers() chain.SynBlocksFromPeers()
} }
} }
err = chain.task.Start(requestblock.Start, requestblock.End, cb) err = chain.syncTask.Start(requestblock.Start, requestblock.End, cb)
if err != nil { if err != nil {
return err return err
} }
} }
synlog.Debug("FetchBlock", "Start", requestblock.Start, "End", requestblock.End) synlog.Info("FetchBlock", "Start", requestblock.Start, "End", requestblock.End)
msg := chain.client.NewMessage("p2p", types.EventFetchBlocks, &requestblock) msg := chain.client.NewMessage("p2p", types.EventFetchBlocks, &requestblock)
Err := chain.client.Send(msg, true) Err := chain.client.Send(msg, true)
if Err != nil { if Err != nil {
...@@ -426,6 +426,20 @@ func (chain *BlockChain) GetPeers() PeerInfoList { ...@@ -426,6 +426,20 @@ func (chain *BlockChain) GetPeers() PeerInfoList {
return peers return peers
} }
//GetPeersMap 获取peers的map列表方便查找
func (chain *BlockChain) GetPeersMap() map[string]bool {
peerMaxBlklock.Lock()
defer peerMaxBlklock.Unlock()
peersmap := make(map[string]bool)
if chain.peerList != nil {
for _, peer := range chain.peerList {
peersmap[peer.Name] = true
}
}
return peersmap
}
//IsFaultPeer 判断指定pid是否在故障faultPeerList中 //IsFaultPeer 判断指定pid是否在故障faultPeerList中
func (chain *BlockChain) IsFaultPeer(pid string) bool { func (chain *BlockChain) IsFaultPeer(pid string) bool {
faultpeerlock.Lock() faultpeerlock.Lock()
...@@ -562,11 +576,10 @@ func (chain *BlockChain) SynBlocksFromPeers() { ...@@ -562,11 +576,10 @@ func (chain *BlockChain) SynBlocksFromPeers() {
} else { } else {
atomic.CompareAndSwapInt32(&chain.isbatchsync, 0, 1) atomic.CompareAndSwapInt32(&chain.isbatchsync, 0, 1)
} }
//synlog.Info("SynBlocksFromPeers", "isbatchsync", chain.isbatchsync)
//如果任务正常,那么不重复启动任务 //如果任务正常,那么不重复启动任务
if chain.task.InProgress() { if chain.syncTask.InProgress() {
synlog.Info("chain task InProgress") synlog.Info("chain syncTask InProgress")
return return
} }
//获取peers的最新高度.处理没有收到广播block的情况 //获取peers的最新高度.处理没有收到广播block的情况
...@@ -759,78 +772,15 @@ func (chain *BlockChain) ProcBlockHeaders(headers *types.Headers, pid string) er ...@@ -759,78 +772,15 @@ func (chain *BlockChain) ProcBlockHeaders(headers *types.Headers, pid string) er
peermaxheight := peerinfo.Height peermaxheight := peerinfo.Height
//启动一个线程在后台获取分叉的blcok //启动一个线程在后台获取分叉的blcok
if chain.forktask.InProgress() { if chain.downLoadTask.InProgress() {
synlog.Info("ProcBlockHeaders forktask.InProgress") synlog.Info("ProcBlockHeaders downLoadTask.InProgress")
return nil return nil
} }
go chain.ProcBlockChainFork(ForkHeight, peermaxheight, pid) //在快速下载block阶段不处理fork的处理
return nil if !GetDownloadSyncStatus() {
} go chain.ProcDownLoadBlocks(ForkHeight, peermaxheight, []string{pid})
//ProcBlockChainFork 处理从peer获取的headers消息
func (chain *BlockChain) ProcBlockChainFork(forkStartHeight int64, forkEndHeight int64, pid string) {
forkinfo := chain.GetForkInfo()
//可能存在上次fork 处理过程中下载区块超时,forktask任务退出,但forkinfo没有恢复成默认值
if forkinfo.ForkStartHeight != -1 || forkinfo.ForkEndHeight != -1 {
synlog.Error("ProcBlockChainFork Fork processing", "pid", forkinfo.ForkPid, "ForkStartHeight", forkinfo.ForkStartHeight, "ForkEndHeight", forkinfo.ForkEndHeight)
}
chain.DefaultForkInfo()
chain.InitForkInfo(forkStartHeight, forkEndHeight, pid)
chain.ReqForkBlocks()
}
//InitForkInfo 开始新的fork处理
func (chain *BlockChain) InitForkInfo(forkStartHeight int64, forkEndHeight int64, pid string) {
chain.forklock.Lock()
defer chain.forklock.Unlock()
chain.forkInfo.ForkStartHeight = forkStartHeight
chain.forkInfo.ForkEndHeight = forkEndHeight
chain.forkInfo.ForkPid = pid
synlog.Debug("InitForkInfo Fork process begin", "ForkStartHeight", forkStartHeight, "ForkEndHeight", forkEndHeight, "pid", pid)
}
//DefaultForkInfo 将forkinfo恢复成默认值
func (chain *BlockChain) DefaultForkInfo() {
chain.forklock.Lock()
defer chain.forklock.Unlock()
chain.forkInfo.ForkStartHeight = -1
chain.forkInfo.ForkEndHeight = -1
chain.forkInfo.ForkPid = ""
synlog.Debug("DefaultForkInfo")
}
//GetForkInfo 获取forkinfo
func (chain *BlockChain) GetForkInfo() *ForkInfo {
chain.forklock.Lock()
defer chain.forklock.Unlock()
return chain.forkInfo
}
//UpdateForkStartHeight 更新fork 请求的起始block高度
func (chain *BlockChain) UpdateForkStartHeight(forkStartHeight int64) {
chain.forklock.Lock()
defer chain.forklock.Unlock()
chain.forkInfo.ForkStartHeight = forkStartHeight
synlog.Debug("UpdateForkStartHeight", "ForkStartHeight", chain.forkInfo.ForkStartHeight, "ForkEndHeight", chain.forkInfo.ForkEndHeight, "pid", chain.forkInfo.ForkPid)
}
//ReqForkBlocks 请求fork处理的blocks
func (chain *BlockChain) ReqForkBlocks() {
forkinfo := chain.GetForkInfo()
if forkinfo.ForkStartHeight != -1 && forkinfo.ForkEndHeight != -1 && forkinfo.ForkPid != "" {
synlog.Info("ReqForkBlocks", "ForkStartHeight", forkinfo.ForkStartHeight, "ForkEndHeight", forkinfo.ForkEndHeight, "pid", forkinfo.ForkPid)
err := chain.FetchBlock(forkinfo.ForkStartHeight, forkinfo.ForkEndHeight, []string{forkinfo.ForkPid}, true)
if err != nil {
synlog.Error("ReqForkBlocks FetchBlock ", "err", err)
}
} }
return nil
} }
//ProcAddBlockHeadersMsg 处理从peer获取的headers消息 //ProcAddBlockHeadersMsg 处理从peer获取的headers消息
...@@ -1019,7 +969,13 @@ func (chain *BlockChain) GetBestChainPids() []string { ...@@ -1019,7 +969,13 @@ func (chain *BlockChain) GetBestChainPids() []string {
bestpeerlock.Lock() bestpeerlock.Lock()
defer bestpeerlock.Unlock() defer bestpeerlock.Unlock()
peersmap := chain.GetPeersMap()
for key, value := range chain.bestChainPeerList { for key, value := range chain.bestChainPeerList {
if !peersmap[value.Peer.Name] {
delete(chain.bestChainPeerList, value.Peer.Name)
synlog.Debug("GetBestChainPids:delete", "peer", value.Peer.Name)
continue
}
if value.IsBestChain { if value.IsBestChain {
ok := chain.IsFaultPeer(value.Peer.Name) ok := chain.IsFaultPeer(value.Peer.Name)
if !ok { if !ok {
...@@ -1027,7 +983,7 @@ func (chain *BlockChain) GetBestChainPids() []string { ...@@ -1027,7 +983,7 @@ func (chain *BlockChain) GetBestChainPids() []string {
} }
} }
} }
synlog.Debug("GetBestChainPids ", "pids", PeerPids) synlog.Debug("GetBestChainPids", "pids", PeerPids)
return PeerPids return PeerPids
} }
......
...@@ -47,9 +47,9 @@ type BlockChain struct { ...@@ -47,9 +47,9 @@ type BlockChain struct {
blockStore *BlockStore blockStore *BlockStore
pushseq *pushseq pushseq *pushseq
//cache 缓存block方便快速查询 //cache 缓存block方便快速查询
cfg *types.BlockChain cfg *types.BlockChain
task *Task syncTask *Task
forktask *Task downLoadTask *Task
query *Query query *Query
...@@ -98,9 +98,9 @@ type BlockChain struct { ...@@ -98,9 +98,9 @@ type BlockChain struct {
//记录futureblocks //记录futureblocks
futureBlocks *lru.Cache // future blocks are broadcast later processing futureBlocks *lru.Cache // future blocks are broadcast later processing
//fork block req //downLoad block info
forkInfo *ForkInfo downLoadInfo *DownLoadInfo
forklock sync.Mutex downLoadlock sync.Mutex
} }
//New new //New new
...@@ -119,8 +119,8 @@ func New(cfg *types.BlockChain) *BlockChain { ...@@ -119,8 +119,8 @@ func New(cfg *types.BlockChain) *BlockChain {
recvwg: &sync.WaitGroup{}, recvwg: &sync.WaitGroup{},
tickerwg: &sync.WaitGroup{}, tickerwg: &sync.WaitGroup{},
task: newTask(300 * time.Second), //考虑到区块交易多时执行耗时,需要延长task任务的超时时间 syncTask: newTask(300 * time.Second), //考虑到区块交易多时执行耗时,需要延长task任务的超时时间
forktask: newTask(300 * time.Second), downLoadTask: newTask(300 * time.Second),
quit: make(chan struct{}), quit: make(chan struct{}),
synblock: make(chan struct{}, 1), synblock: make(chan struct{}, 1),
...@@ -133,7 +133,7 @@ func New(cfg *types.BlockChain) *BlockChain { ...@@ -133,7 +133,7 @@ func New(cfg *types.BlockChain) *BlockChain {
faultPeerList: make(map[string]*FaultPeerInfo), faultPeerList: make(map[string]*FaultPeerInfo),
bestChainPeerList: make(map[string]*BestPeerInfo), bestChainPeerList: make(map[string]*BestPeerInfo),
futureBlocks: futureBlocks, futureBlocks: futureBlocks,
forkInfo: &ForkInfo{}, downLoadInfo: &DownLoadInfo{},
} }
return blockchain return blockchain
...@@ -257,8 +257,8 @@ func (chain *BlockChain) InitBlockChain() { ...@@ -257,8 +257,8 @@ func (chain *BlockChain) InitBlockChain() {
// 定时处理futureblock // 定时处理futureblock
go chain.UpdateRoutine() go chain.UpdateRoutine()
} }
//初始化默认forkinfo //初始化默认DownLoadInfo
chain.DefaultForkInfo() chain.DefaultDownLoadInfo()
} }
func (chain *BlockChain) getStateHash() []byte { func (chain *BlockChain) getStateHash() []byte {
......
...@@ -121,6 +121,12 @@ func TestBlockChain(t *testing.T) { ...@@ -121,6 +121,12 @@ func TestBlockChain(t *testing.T) {
testDelBlock(t, blockchain, curBlock) testDelBlock(t, blockchain, curBlock)
testIsRecordFaultErr(t) testIsRecordFaultErr(t)
testGetsynBlkHeight(t, blockchain)
testProcDelChainBlockMsg(t, mock33, blockchain)
testFaultPeer(t, blockchain)
testCheckBlock(t, blockchain)
testWriteBlockToDbTemp(t, blockchain)
testReadBlockToExec(t, blockchain)
} }
func testProcAddBlockMsg(t *testing.T, mock33 *testnode.Chain33Mock, blockchain *blockchain.BlockChain) { func testProcAddBlockMsg(t *testing.T, mock33 *testnode.Chain33Mock, blockchain *blockchain.BlockChain) {
...@@ -923,11 +929,11 @@ func testProcBlockChainFork(t *testing.T, blockchain *blockchain.BlockChain) { ...@@ -923,11 +929,11 @@ func testProcBlockChainFork(t *testing.T, blockchain *blockchain.BlockChain) {
chainlog.Info("testProcBlockChainFork begin --------------------") chainlog.Info("testProcBlockChainFork begin --------------------")
curheight := blockchain.GetBlockHeight() curheight := blockchain.GetBlockHeight()
blockchain.ProcBlockChainFork(curheight-1, curheight+256, "self") blockchain.ProcDownLoadBlocks(curheight-1, curheight+256, []string{"self"})
chainlog.Info("testProcBlockChainFork end --------------------") chainlog.Info("testProcBlockChainFork end --------------------")
} }
func testAddBlockSeqCB(t *testing.T, blockchain *blockchain.BlockChain) { func testAddBlockSeqCB(t *testing.T, chain *blockchain.BlockChain) {
chainlog.Info("testAddBlockSeqCB begin ---------------------") chainlog.Info("testAddBlockSeqCB begin ---------------------")
cb := &types.BlockSeqCB{ cb := &types.BlockSeqCB{
...@@ -935,11 +941,11 @@ func testAddBlockSeqCB(t *testing.T, blockchain *blockchain.BlockChain) { ...@@ -935,11 +941,11 @@ func testAddBlockSeqCB(t *testing.T, blockchain *blockchain.BlockChain) {
URL: "http://192.168.1.107:15760", URL: "http://192.168.1.107:15760",
Encode: "json", Encode: "json",
} }
blockchain.MaxSeqCB = 1
err := blockchain.ProcAddBlockSeqCB(cb) err := chain.ProcAddBlockSeqCB(cb)
require.NoError(t, err) require.NoError(t, err)
cbs, err := blockchain.ProcListBlockSeqCB() cbs, err := chain.ProcListBlockSeqCB()
require.NoError(t, err) require.NoError(t, err)
exist := false exist := false
for _, temcb := range cbs.Items { for _, temcb := range cbs.Items {
...@@ -950,10 +956,22 @@ func testAddBlockSeqCB(t *testing.T, blockchain *blockchain.BlockChain) { ...@@ -950,10 +956,22 @@ func testAddBlockSeqCB(t *testing.T, blockchain *blockchain.BlockChain) {
if !exist { if !exist {
t.Error("testAddBlockSeqCB listSeqCB fail", "cb", cb, "cbs", cbs) t.Error("testAddBlockSeqCB listSeqCB fail", "cb", cb, "cbs", cbs)
} }
num := blockchain.ProcGetSeqCBLastNum(cb.Name) num := chain.ProcGetSeqCBLastNum(cb.Name)
if num != -1 { if num != -1 {
t.Error("testAddBlockSeqCB getSeqCBLastNum", "num", num, "name", cb.Name) t.Error("testAddBlockSeqCB getSeqCBLastNum", "num", num, "name", cb.Name)
} }
cb2 := &types.BlockSeqCB{
Name: "test1",
URL: "http://192.168.1.107:15760",
Encode: "json",
}
err = chain.ProcAddBlockSeqCB(cb2)
if err != types.ErrTooManySeqCB {
t.Error("testAddBlockSeqCB", "cb", cb2, "err", err)
}
chainlog.Info("testAddBlockSeqCB end -------------------------") chainlog.Info("testAddBlockSeqCB end -------------------------")
} }
func testIsRecordFaultErr(t *testing.T) { func testIsRecordFaultErr(t *testing.T) {
...@@ -962,5 +980,132 @@ func testIsRecordFaultErr(t *testing.T) { ...@@ -962,5 +980,132 @@ func testIsRecordFaultErr(t *testing.T) {
if isok { if isok {
t.Error("testIsRecordFaultErr IsRecordFaultErr", "isok", isok) t.Error("testIsRecordFaultErr IsRecordFaultErr", "isok", isok)
} }
chainlog.Info("testIsRecordFaultErr begin ---------------------") chainlog.Info("testIsRecordFaultErr end ---------------------")
}
func testProcDelChainBlockMsg(t *testing.T, mock33 *testnode.Chain33Mock, blockchain *blockchain.BlockChain) {
chainlog.Info("testProcDelChainBlockMsg begin --------------------")
curheight := blockchain.GetBlockHeight()
block, err := blockchain.GetBlock(curheight)
require.NoError(t, err)
var parablockDetail types.ParaChainBlockDetail
parablockDetail.Blockdetail = block
parablockDetail.Sequence = curheight
msgGen := mock33.GetClient().NewMessage("blockchain", types.EventDelParaChainBlockDetail, &parablockDetail)
mock33.GetClient().Send(msgGen, true)
mock33.GetClient().Wait(msgGen)
chainlog.Info("testProcDelChainBlockMsg end --------------------")
}
func testGetsynBlkHeight(t *testing.T, chain *blockchain.BlockChain) {
chainlog.Info("testGetsynBlkHeight begin --------------------")
curheight := chain.GetBlockHeight()
chain.UpdatesynBlkHeight(curheight)
height := chain.GetsynBlkHeight()
if height != curheight {
chainlog.Error("testGetsynBlkHeight", "curheight", curheight, "height", height)
}
//get peerinfo
peerinfo := chain.GetPeerInfo("self")
if peerinfo != nil {
chainlog.Error("testGetsynBlkHeight:GetPeerInfo", "peerinfo", peerinfo)
}
maxpeer := chain.GetMaxPeerInfo()
if maxpeer != nil {
chainlog.Error("testGetsynBlkHeight:GetMaxPeerInfo", "maxpeer", maxpeer)
}
chainlog.Info("testGetsynBlkHeight end --------------------")
}
func testFaultPeer(t *testing.T, chain *blockchain.BlockChain) {
chainlog.Info("testFaultPeer begin ---------------------")
curheight := chain.GetBlockHeight()
block, err := chain.GetBlock(curheight)
require.NoError(t, err)
isok := chain.IsFaultPeer("self")
if isok {
t.Error("testFaultPeer:IsFaultPeer")
}
//记录故障peer信息
chain.RecordFaultPeer("self", curheight+1, block.Block.Hash(), types.ErrSign)
var faultnode blockchain.FaultPeerInfo
var peerinfo blockchain.PeerInfo
peerinfo.Name = "self"
faultnode.Peer = &peerinfo
faultnode.FaultHeight = curheight + 1
faultnode.FaultHash = block.Block.Hash()
faultnode.ErrInfo = types.ErrSign
faultnode.ReqFlag = false
chain.AddFaultPeer(&faultnode)
peer := chain.GetFaultPeer("self")
if peer == nil {
t.Error("testFaultPeer:GetFaultPeer is nil")
}
chain.UpdateFaultPeer("self", true)
chain.RemoveFaultPeer("self")
chainlog.Info("testFaultPeer end ---------------------")
}
func testCheckBlock(t *testing.T, chain *blockchain.BlockChain) {
curheight := chain.GetBlockHeight()
//chain.CheckHeightNoIncrease()
chain.FetchBlockHeaders(0, curheight, "self")
header, err := chain.ProcGetLastHeaderMsg()
var blockheader types.Header
if header != nil && err == nil {
blockheader.Version = header.Version
blockheader.ParentHash = header.ParentHash
blockheader.TxHash = header.TxHash
blockheader.StateHash = header.StateHash
blockheader.Height = header.Height
blockheader.BlockTime = header.BlockTime
blockheader.TxCount = header.TxCount
blockheader.Hash = header.Hash
blockheader.Difficulty = header.Difficulty
blockheader.Signature = header.Signature
}
var blockheaders types.Headers
blockheaders.Items = append(blockheaders.Items, &blockheader)
chain.ProcAddBlockHeadersMsg(&blockheaders, "self")
chain.ProcBlockHeaders(&blockheaders, "self")
}
func testReadBlockToExec(t *testing.T, chain *blockchain.BlockChain) {
chainlog.Info("testReadBlockToExec begin ---------------------")
curheight := chain.GetBlockHeight()
chain.ReadBlockToExec(curheight+1, false)
chainlog.Info("testReadBlockToExec end ---------------------")
}
func testWriteBlockToDbTemp(t *testing.T, chain *blockchain.BlockChain) {
chainlog.Info("WriteBlockToDbTemp begin ---------------------")
curheight := chain.GetBlockHeight()
block, err := chain.GetBlock(curheight)
if err != nil {
t.Error("testWriteBlockToDbTemp", "err", err)
}
var rawblock types.Block
rawblock.Version = block.Block.Version
rawblock.ParentHash = block.Block.ParentHash
rawblock.TxHash = block.Block.TxHash
rawblock.StateHash = block.Block.StateHash
rawblock.BlockTime = block.Block.BlockTime
rawblock.Difficulty = block.Block.Difficulty
rawblock.MainHash = block.Block.MainHash
rawblock.MainHeight = block.Block.MainHeight
rawblock.Height = block.Block.Height + 1
err = chain.WriteBlockToDbTemp(&rawblock)
if err != nil {
t.Error("testWriteBlockToDbTemp", "err", err)
}
chainlog.Info("WriteBlockToDbTemp end ---------------------")
} }
This diff is collapsed.
...@@ -157,19 +157,30 @@ func (chain *BlockChain) getBlocks(msg *queue.Message) { ...@@ -157,19 +157,30 @@ func (chain *BlockChain) getBlocks(msg *queue.Message) {
} }
func (chain *BlockChain) addBlock(msg *queue.Message) { func (chain *BlockChain) addBlock(msg *queue.Message) {
//var block *types.Block
var reply types.Reply var reply types.Reply
reply.IsOk = true reply.IsOk = true
blockpid := msg.Data.(*types.BlockPid) blockpid := msg.Data.(*types.BlockPid)
_, err := chain.ProcAddBlockMsg(false, &types.BlockDetail{Block: blockpid.Block}, blockpid.Pid) //chainlog.Error("addBlock", "height", blockpid.Block.Height, "pid", blockpid.Pid)
if err != nil { if GetDownloadSyncStatus() {
chainlog.Error("ProcAddBlockMsg", "height", blockpid.Block.Height, "err", err.Error()) //downLoadTask 运行时设置对应的blockdone
reply.IsOk = false if chain.downLoadTask.InProgress() {
reply.Msg = []byte(err.Error()) chain.downLoadTask.Done(blockpid.Block.GetHeight())
}
err := chain.WriteBlockToDbTemp(blockpid.Block)
if err != nil {
chainlog.Error("WriteBlockToDbTemp", "height", blockpid.Block.Height, "err", err.Error())
reply.IsOk = false
reply.Msg = []byte(err.Error())
}
} else { } else {
//chain.notifySync() _, err := chain.ProcAddBlockMsg(false, &types.BlockDetail{Block: blockpid.Block}, blockpid.Pid)
if err != nil {
chainlog.Error("ProcAddBlockMsg", "height", blockpid.Block.Height, "err", err.Error())
reply.IsOk = false
reply.Msg = []byte(err.Error())
}
chainlog.Debug("EventAddBlock", "height", blockpid.Block.Height, "pid", blockpid.Pid, "success", "ok")
} }
chainlog.Debug("EventAddBlock", "height", blockpid.Block.Height, "pid", blockpid.Pid, "success", "ok")
msg.Reply(chain.client.NewMessage("p2p", types.EventReply, &reply)) msg.Reply(chain.client.NewMessage("p2p", types.EventReply, &reply))
} }
......
...@@ -389,7 +389,7 @@ func (b *BlockChain) connectBlock(node *blockNode, blockdetail *types.BlockDetai ...@@ -389,7 +389,7 @@ func (b *BlockChain) connectBlock(node *blockNode, blockdetail *types.BlockDetai
chainlog.Debug("connectBlock SendAddBlockEvent", "err", err) chainlog.Debug("connectBlock SendAddBlockEvent", "err", err)
} }
// 通知此block已经处理完,主要处理孤儿节点时需要设置 // 通知此block已经处理完,主要处理孤儿节点时需要设置
b.task.Done(blockdetail.Block.GetHeight()) b.syncTask.Done(blockdetail.Block.GetHeight())
//广播此block到全网络 //广播此block到全网络
if node.broadcast { if node.broadcast {
......
...@@ -240,14 +240,14 @@ func (chain *BlockChain) ProcAddBlockMsg(broadcast bool, blockdetail *types.Bloc ...@@ -240,14 +240,14 @@ func (chain *BlockChain) ProcAddBlockMsg(broadcast bool, blockdetail *types.Bloc
blockdetail = b blockdetail = b
} }
//非孤儿block或者已经存在的block //非孤儿block或者已经存在的block
if chain.task.InProgress() { if chain.syncTask.InProgress() {
if (!isorphan && err == nil) || (err == types.ErrBlockExist) { if (!isorphan && err == nil) || (err == types.ErrBlockExist) {
chain.task.Done(blockdetail.Block.GetHeight()) chain.syncTask.Done(blockdetail.Block.GetHeight())
} }
} }
//forktask 运行时设置对应的blockdone //downLoadTask 运行时设置对应的blockdone
if chain.forktask.InProgress() { if chain.downLoadTask.InProgress() {
chain.forktask.Done(blockdetail.Block.GetHeight()) chain.downLoadTask.Done(blockdetail.Block.GetHeight())
} }
//此处只更新广播block的高度 //此处只更新广播block的高度
if broadcast { if broadcast {
......
...@@ -300,11 +300,23 @@ function transfer() { ...@@ -300,11 +300,23 @@ function transfer() {
done done
${CLI} account balance -a 12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv -e coins ${CLI} account balance -a 12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv -e coins
balance=$(${CLI} account balance -a 12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv -e coins | jq -r ".balance")
if [ "${balance}" != "10.0000" ]; then local times=100
echo "wrong balance=$balance, should not be 10.0000" while true; do
exit 1 balance=$(${CLI} account balance -a 12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv -e coins | jq -r ".balance")
fi echo "account balance is ${balance}, expect 10.0000 "
if [ "${balance}" != "10.0000" ]; then
block_wait 2
times=$((times - 1))
if [ $times -le 0 ]; then
echo "account balance transfer failed"
exit 1
fi
else
echo "account balance transfer success"
break
fi
done
} }
......
Title="chain33" Title="chain33"
TestNet=true TestNet=true
CoinSymbol="bty"
[log] [log]
# 日志级别,支持debug(dbug)/info/warn/error(eror)/crit # 日志级别,支持debug(dbug)/info/warn/error(eror)/crit
...@@ -197,4 +198,4 @@ superManager=[ ...@@ -197,4 +198,4 @@ superManager=[
[health] [health]
listenAddr="localhost:8805" listenAddr="localhost:8805"
checkInterval=1 checkInterval=1
unSyncMaxTimes=2 unSyncMaxTimes=2
\ No newline at end of file
Title="chain33" Title="chain33"
TestNet=true TestNet=true
FixTime=false FixTime=false
CoinSymbol="bty"
[log] [log]
# 日志级别,支持debug(dbug)/info/warn/error(eror)/crit # 日志级别,支持debug(dbug)/info/warn/error(eror)/crit
...@@ -239,6 +240,7 @@ minerwhitelist=["*"] ...@@ -239,6 +240,7 @@ minerwhitelist=["*"]
isFree=false isFree=false
#执行器执行所需最小费用,低于Mempool和Wallet设置的MinFee,在minExecFee = 0 的情况下,isFree = true才会生效 #执行器执行所需最小费用,低于Mempool和Wallet设置的MinFee,在minExecFee = 0 的情况下,isFree = true才会生效
minExecFee=100000 minExecFee=100000
maxExecFee=1000000000
#是否开启stat插件 #是否开启stat插件
enableStat=false enableStat=false
#是否开启MVCC插件 #是否开启MVCC插件
......
syntax = "proto3";
package calculator;
// calculator 合约交易行为总类型
message CalculatorAction {
oneof value {
Add add = 1;
Subtract sub = 2;
Multiply mul = 3;
Divide div = 4;
}
int32 ty = 5;
}
message Add {
int32 summand = 1; //被加数
int32 addend = 2; //加数
}
message AddLog {
int32 sum = 1; //和
}
message Subtract {
int32 minuend = 1; //被减数
int32 subtrahend = 2; //减数
}
message SubLog {
int32 remainder = 1; //差
}
message Multiply {
int32 faciend = 1; //被乘数
int32 multiplier = 2; //乘数
}
message MultiplyLog {
int32 product = 1; //积
}
message Divide {
int32 dividend = 1; //被除数
int32 divisor = 2; //除数
}
message DivideLog {
int32 quotient = 1; //商
int32 remain = 2; //余数
}
message ReqQueryCalcCount {
string action = 1;
}
message ReplyQueryCalcCount {
int32 count = 1;
}
service calculator {
rpc QueryCalcCount(ReqQueryCalcCount) returns (ReplyQueryCalcCount) {}
}
This diff is collapsed.
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
### 编译 ### 编译
``` ```
//本地存在chain33代码,该步骤可省略 //本地存在chain33代码,该步骤可省略
$ git clone https://github.com/33cn/chain33.git $GOPATH/src/github.com/33cn/chain33 $ go get github.com/33cn/chain33
//编译chain33 tools //编译chain33 tools
$ go build -i -o $GOPATH/bin/chain33-tool github.com/33cn/chain33/cmd/tools $ go build -i -o $GOPATH/bin/chain33-tool github.com/33cn/chain33/cmd/tools
``` ```
...@@ -36,8 +36,6 @@ $ chain33-tool gendapp -n demo -p ./demo.proto ...@@ -36,8 +36,6 @@ $ chain33-tool gendapp -n demo -p ./demo.proto
// 指定输出包路径 // 指定输出包路径
$ chain33-tool gendapp -n demo -p ./demo.proto -o github.com/33cn/chain33/plugin/dapp/ $ chain33-tool gendapp -n demo -p ./demo.proto -o github.com/33cn/chain33/plugin/dapp/
//生成proto
cd proto && chmod +x ./create_protobuf.sh && make
``` ```
### proto规范 ### proto规范
* 定义合约交易行为结构,采用**oneof value**形式,且名称必须为**NameAction**格式, * 定义合约交易行为结构,采用**oneof value**形式,且名称必须为**NameAction**格式,
...@@ -51,6 +49,11 @@ message DemoAction { ...@@ -51,6 +49,11 @@ message DemoAction {
int32 ty = 3; int32 ty = 3;
} }
``` ```
* package name设为合约名,适配后续生成目录结构
```
package demo;
```
* 定义service,直接以合约名作为名称 * 定义service,直接以合约名作为名称
``` ```
service demo { service demo {
...@@ -61,7 +64,7 @@ service demo { ...@@ -61,7 +64,7 @@ service demo {
### 代码 ### 代码
#####目录结构,以demo合约为例 ##### 目录结构,以demo合约为例
``` ```
demo demo
├── cmd //包含官方ci集成相关脚本 ├── cmd //包含官方ci集成相关脚本
...@@ -84,10 +87,18 @@ demo ...@@ -84,10 +87,18 @@ demo
│   ├── rpc.go │   ├── rpc.go
│   └── types.go │   └── types.go
└── types //类型模块 └── types //类型模块
└── demo.go └── demo
└── demo.go
``` ```
##### 生成pb.go文件
```
//进入到上述proto目录执行相关脚本,将会在types目录下生成对应pb.go文件
$ cd proto && chmod +x ./create_protobuf.sh && make
```
##### 后续开发 ##### 后续开发
在生成代码基础上,需要实现交易创建,执行,及所需rpc服务,初次开发可以参考官方的echo合约 在生成代码基础上,需要实现交易创建,执行,及所需rpc服务<br/>
> github.com/33cn/plugin/plugin/dapp/echo 初次开发可以参考官方简单计算器合约
[开发步骤](https://github.com/33cn/chain33/blob/master/cmd/tools/doc/gencalculator.md)
...@@ -14,7 +14,8 @@ type ICodeFile interface { ...@@ -14,7 +14,8 @@ type ICodeFile interface {
GetCodeType() string GetCodeType() string
GetDirName() string GetDirName() string
GetFiles() map[string]string //key:filename, val:file content GetFiles() map[string]string //key:filename, val:file content
GetReplaceTags() []string GetDirReplaceTags() []string
GetFileReplaceTags() []string
} }
//RegisterCodeFile regeister code file //RegisterCodeFile regeister code file
...@@ -47,8 +48,14 @@ func (CodeFile) GetFiles() map[string]string { ...@@ -47,8 +48,14 @@ func (CodeFile) GetFiles() map[string]string {
return nil return nil
} }
//GetReplaceTags get replace tags //GetDirReplaceTags get directory replace tags
func (CodeFile) GetReplaceTags() []string { func (CodeFile) GetDirReplaceTags() []string {
return nil
}
//GetFileReplaceTags get file replace tags
func (CodeFile) GetFileReplaceTags() []string {
return nil return nil
} }
...@@ -30,7 +30,7 @@ func (c commandsCodeFile) GetFiles() map[string]string { ...@@ -30,7 +30,7 @@ func (c commandsCodeFile) GetFiles() map[string]string {
} }
} }
func (c commandsCodeFile) GetReplaceTags() []string { func (c commandsCodeFile) GetFileReplaceTags() []string {
return []string{types.TagExecName} return []string{types.TagExecName}
} }
...@@ -39,7 +39,9 @@ var ( ...@@ -39,7 +39,9 @@ var (
commandsFileContent = `/*Package commands implement dapp client commands*/ commandsFileContent = `/*Package commands implement dapp client commands*/
package commands package commands
import "github.com/spf13/cobra" import (
"github.com/spf13/cobra"
)
/* /*
* 实现合约对应客户端 * 实现合约对应客户端
......
...@@ -26,7 +26,7 @@ func (execCode) GetFiles() map[string]string { ...@@ -26,7 +26,7 @@ func (execCode) GetFiles() map[string]string {
} }
} }
func (execCode) GetReplaceTags() []string { func (execCode) GetFileReplaceTags() []string {
return []string{types.TagExecName, types.TagImportPath, types.TagClassName, types.TagExecFileContent} return []string{types.TagExecName, types.TagImportPath, types.TagClassName, types.TagExecFileContent}
} }
...@@ -42,7 +42,7 @@ func (execLocalCode) GetFiles() map[string]string { ...@@ -42,7 +42,7 @@ func (execLocalCode) GetFiles() map[string]string {
} }
} }
func (execLocalCode) GetReplaceTags() []string { func (execLocalCode) GetFileReplaceTags() []string {
return []string{types.TagExecName, types.TagImportPath, types.TagExecLocalFileContent} return []string{types.TagExecName, types.TagImportPath, types.TagExecLocalFileContent}
} }
...@@ -58,7 +58,7 @@ func (execDelLocalCode) GetFiles() map[string]string { ...@@ -58,7 +58,7 @@ func (execDelLocalCode) GetFiles() map[string]string {
} }
} }
func (execDelLocalCode) GetReplaceTags() []string { func (execDelLocalCode) GetFileReplaceTags() []string {
return []string{types.TagExecName, types.TagImportPath, types.TagExecDelLocalFileContent} return []string{types.TagExecName, types.TagImportPath, types.TagExecDelLocalFileContent}
} }
...@@ -68,7 +68,7 @@ var ( ...@@ -68,7 +68,7 @@ var (
execContent = `package executor execContent = `package executor
import ( import (
ptypes "${IMPORTPATH}/${EXECNAME}/types" ptypes "${IMPORTPATH}/${EXECNAME}/types/${EXECNAME}"
"github.com/33cn/chain33/types" "github.com/33cn/chain33/types"
) )
...@@ -83,7 +83,7 @@ ${EXECFILECONTENT}` ...@@ -83,7 +83,7 @@ ${EXECFILECONTENT}`
execLocalContent = `package executor execLocalContent = `package executor
import ( import (
ptypes "${IMPORTPATH}/${EXECNAME}/types" ptypes "${IMPORTPATH}/${EXECNAME}/types/${EXECNAME}"
"github.com/33cn/chain33/types" "github.com/33cn/chain33/types"
) )
...@@ -98,7 +98,7 @@ ${EXECLOCALFILECONTENT}` ...@@ -98,7 +98,7 @@ ${EXECLOCALFILECONTENT}`
execDelContent = `package executor execDelContent = `package executor
import ( import (
ptypes "${IMPORTPATH}/${EXECNAME}/types" ptypes "${IMPORTPATH}/${EXECNAME}/types/${EXECNAME}"
"github.com/33cn/chain33/types" "github.com/33cn/chain33/types"
) )
......
...@@ -31,7 +31,7 @@ func (c executorCodeFile) GetFiles() map[string]string { ...@@ -31,7 +31,7 @@ func (c executorCodeFile) GetFiles() map[string]string {
} }
} }
func (c executorCodeFile) GetReplaceTags() []string { func (c executorCodeFile) GetFileReplaceTags() []string {
return []string{types.TagExecName, types.TagImportPath, types.TagClassName} return []string{types.TagExecName, types.TagImportPath, types.TagClassName}
} }
...@@ -42,7 +42,7 @@ var ( ...@@ -42,7 +42,7 @@ var (
import ( import (
log "github.com/33cn/chain33/common/log/log15" log "github.com/33cn/chain33/common/log/log15"
ptypes "${IMPORTPATH}/${EXECNAME}/types" ptypes "${IMPORTPATH}/${EXECNAME}/types/${EXECNAME}"
drivers "github.com/33cn/chain33/system/dapp" drivers "github.com/33cn/chain33/system/dapp"
"github.com/33cn/chain33/types" "github.com/33cn/chain33/types"
) )
...@@ -55,7 +55,7 @@ import ( ...@@ -55,7 +55,7 @@ import (
var ( var (
//日志 //日志
elog = log.New("module", "execs.${EXECNAME}") elog = log.New("module", "${EXECNAME}.executor")
) )
var driverName = ptypes.${CLASSNAME}X var driverName = ptypes.${CLASSNAME}X
......
...@@ -25,7 +25,7 @@ func (c pluginCodeFile) GetFiles() map[string]string { ...@@ -25,7 +25,7 @@ func (c pluginCodeFile) GetFiles() map[string]string {
} }
} }
func (c pluginCodeFile) GetReplaceTags() []string { func (c pluginCodeFile) GetFileReplaceTags() []string {
return []string{types.TagExecName, types.TagImportPath, types.TagClassName} return []string{types.TagExecName, types.TagImportPath, types.TagClassName}
} }
...@@ -37,7 +37,7 @@ package ${EXECNAME} ...@@ -37,7 +37,7 @@ package ${EXECNAME}
import ( import (
"${IMPORTPATH}/${EXECNAME}/commands" "${IMPORTPATH}/${EXECNAME}/commands"
"${IMPORTPATH}/${EXECNAME}/types" ptypes "${IMPORTPATH}/${EXECNAME}/types/${EXECNAME}"
"${IMPORTPATH}/${EXECNAME}/executor" "${IMPORTPATH}/${EXECNAME}/executor"
"${IMPORTPATH}/${EXECNAME}/rpc" "${IMPORTPATH}/${EXECNAME}/rpc"
"github.com/33cn/chain33/pluginmgr" "github.com/33cn/chain33/pluginmgr"
...@@ -49,7 +49,7 @@ import ( ...@@ -49,7 +49,7 @@ import (
func init() { func init() {
pluginmgr.Register(&pluginmgr.PluginBase{ pluginmgr.Register(&pluginmgr.PluginBase{
Name: types.${CLASSNAME}X, Name: ptypes.${CLASSNAME}X,
ExecName: executor.GetName(), ExecName: executor.GetName(),
Exec: executor.Init, Exec: executor.Init,
Cmd: commands.Cmd, Cmd: commands.Cmd,
......
...@@ -32,6 +32,10 @@ func (protoBase) GetFiles() map[string]string { ...@@ -32,6 +32,10 @@ func (protoBase) GetFiles() map[string]string {
} }
} }
func (protoBase) GetFileReplaceTags() []string {
return []string{types.TagExecName}
}
type protoFile struct { type protoFile struct {
protoBase protoBase
} }
...@@ -42,15 +46,15 @@ func (protoFile) GetFiles() map[string]string { ...@@ -42,15 +46,15 @@ func (protoFile) GetFiles() map[string]string {
} }
} }
func (protoFile) GetReplaceTags() []string { func (protoFile) GetFileReplaceTags() []string {
return []string{types.TagProtoFileContent, types.TagProtoFileAppend, types.TagExecName} return []string{types.TagProtoFileContent, types.TagProtoFileAppend, types.TagExecName}
} }
var ( var (
protoShellName = "create_protobuf.sh" protoShellName = "create_protobuf.sh"
protoShellContent = `#!/bin/sh protoShellContent = `#!/bin/sh
# proto生成命令,将pb.go文件生成到types目录下 # proto生成命令,将pb.go文件生成到types/${EXECNAME}目录下
protoc --go_out=plugins=grpc:../types ./*.proto protoc --go_out=plugins=grpc:../types/${EXECNAME} ./*.proto
` `
makeName = "Makefile" makeName = "Makefile"
......
...@@ -31,7 +31,7 @@ func (c rpcCodeFile) GetFiles() map[string]string { ...@@ -31,7 +31,7 @@ func (c rpcCodeFile) GetFiles() map[string]string {
} }
} }
func (c rpcCodeFile) GetReplaceTags() []string { func (c rpcCodeFile) GetFileReplaceTags() []string {
return []string{types.TagExecName, types.TagImportPath, types.TagClassName} return []string{types.TagExecName, types.TagImportPath, types.TagClassName}
} }
...@@ -53,7 +53,7 @@ var ( ...@@ -53,7 +53,7 @@ var (
typesContent = `package rpc typesContent = `package rpc
import ( import (
ptypes "${IMPORTPATH}/${EXECNAME}/types" ptypes "${IMPORTPATH}/${EXECNAME}/types/${EXECNAME}"
rpctypes "github.com/33cn/chain33/rpc/types" rpctypes "github.com/33cn/chain33/rpc/types"
) )
......
...@@ -5,6 +5,8 @@ ...@@ -5,6 +5,8 @@
package types package types
import ( import (
"os"
"github.com/33cn/chain33/cmd/tools/gencode/base" "github.com/33cn/chain33/cmd/tools/gencode/base"
"github.com/33cn/chain33/cmd/tools/types" "github.com/33cn/chain33/cmd/tools/types"
) )
...@@ -20,7 +22,7 @@ type typesCode struct { ...@@ -20,7 +22,7 @@ type typesCode struct {
func (c typesCode) GetDirName() string { func (c typesCode) GetDirName() string {
return "types" return "types" + string(os.PathSeparator) + "${EXECNAME}"
} }
func (c typesCode) GetFiles() map[string]string { func (c typesCode) GetFiles() map[string]string {
...@@ -30,7 +32,11 @@ func (c typesCode) GetFiles() map[string]string { ...@@ -30,7 +32,11 @@ func (c typesCode) GetFiles() map[string]string {
} }
} }
func (c typesCode) GetReplaceTags() []string { func (c typesCode) GetDirReplaceTags() []string {
return []string{types.TagExecName}
}
func (c typesCode) GetFileReplaceTags() []string {
return []string{types.TagExecName, types.TagClassName, return []string{types.TagExecName, types.TagClassName,
types.TagActionIDText, types.TagTyLogActionType, types.TagActionIDText, types.TagTyLogActionType,
...@@ -39,11 +45,11 @@ func (c typesCode) GetReplaceTags() []string { ...@@ -39,11 +45,11 @@ func (c typesCode) GetReplaceTags() []string {
var ( var (
typesName = "${EXECNAME}.go" typesName = "${EXECNAME}.go"
typesContent = `package types typesContent = `package ${EXECNAME}
import ( import (
"encoding/json" "encoding/json"
log "github.com/33cn/chain33/common/log/log15"
"github.com/33cn/chain33/types" "github.com/33cn/chain33/types"
) )
...@@ -54,7 +60,7 @@ import ( ...@@ -54,7 +60,7 @@ import (
*/ */
// action类型id // action类型id和name,这些常量可以自定义修改
${ACTIONIDTEXT} ${ACTIONIDTEXT}
// log类型id值 // log类型id值
...@@ -63,15 +69,18 @@ ${TYLOGACTIONTYPE} ...@@ -63,15 +69,18 @@ ${TYLOGACTIONTYPE}
var ( var (
//${CLASSNAME}X 执行器名称定义 //${CLASSNAME}X 执行器名称定义
${CLASSNAME}X = "${EXECNAME}" ${CLASSNAME}X = "${EXECNAME}"
//定义action的name和id //定义actionMap
actionMap = ${TYPEMAPTEXT} actionMap = ${TYPEMAPTEXT}
//定义log的id和具体log类型及名称,填入具体自定义log类型 //定义log的id和具体log类型及名称,填入具体自定义log类型
logMap = ${LOGMAPTEXT} logMap = ${LOGMAPTEXT}
tlog = log.New("module", "${EXECNAME}.types")
) )
func init() { func init() {
types.AllowUserExec = append(types.AllowUserExec, []byte(${CLASSNAME}X)) types.AllowUserExec = append(types.AllowUserExec, []byte(${CLASSNAME}X))
types.RegistorExecutor(${CLASSNAME}X, newType()) types.RegistorExecutor(${CLASSNAME}X, newType())
//注册合约启用高度
types.RegisterDappFork(${CLASSNAME}X, "Enable", 0)
} }
type ${EXECNAME}Type struct { type ${EXECNAME}Type struct {
...@@ -102,7 +111,6 @@ func (t *${EXECNAME}Type) GetLogMap() map[int64]*types.LogInfo { ...@@ -102,7 +111,6 @@ func (t *${EXECNAME}Type) GetLogMap() map[int64]*types.LogInfo {
// CreateTx 重载基类接口,实现本合约交易创建,供框架调用 // CreateTx 重载基类接口,实现本合约交易创建,供框架调用
func (t *${EXECNAME}Type) CreateTx(action string, message json.RawMessage) (*types.Transaction, error) { func (t *${EXECNAME}Type) CreateTx(action string, message json.RawMessage) (*types.Transaction, error) {
var tx *types.Transaction var tx *types.Transaction
// pseudo code
//if action == someAction //if action == someAction
//return new tx //return new tx
return tx, types.ErrNotSupport return tx, types.ErrNotSupport
......
...@@ -101,10 +101,18 @@ func (c *GenDappCodeTask) genDappCode() error { ...@@ -101,10 +101,18 @@ func (c *GenDappCodeTask) genDappCode() error {
for _, code := range codeTypes { for _, code := range codeTypes {
dirPath := filepath.Join(c.DappDir, code.GetDirName()) dirName := code.GetDirName()
_ = os.Mkdir(dirPath, os.ModePerm) for _, tag := range code.GetDirReplaceTags() {
dirName = strings.Replace(dirName, tag, c.replacePairs[tag], -1)
}
dirPath := filepath.Join(c.DappDir, dirName)
err := os.MkdirAll(dirPath, os.ModePerm)
if err != nil {
mlog.Error("MakeCodeDir", "Err", err.Error(), "DirPath", dirPath)
return err
}
files := code.GetFiles() files := code.GetFiles()
tags := code.GetReplaceTags() tags := code.GetFileReplaceTags()
for name, content := range files { for name, content := range files {
...@@ -113,7 +121,7 @@ func (c *GenDappCodeTask) genDappCode() error { ...@@ -113,7 +121,7 @@ func (c *GenDappCodeTask) genDappCode() error {
content = strings.Replace(content, tag, c.replacePairs[tag], -1) content = strings.Replace(content, tag, c.replacePairs[tag], -1)
} }
_, err := util.WriteStringToFile(filepath.Join(dirPath, name), content) _, err = util.WriteStringToFile(filepath.Join(dirPath, name), content)
if err != nil { if err != nil {
mlog.Error("GenNewCodeFile", "Err", err.Error(), "CodeFile", filepath.Join(dirPath, name)) mlog.Error("GenNewCodeFile", "Err", err.Error(), "CodeFile", filepath.Join(dirPath, name))
......
...@@ -60,8 +60,9 @@ func readDappActionFromProto(protoContent, actionName string) ([]*actionInfoItem ...@@ -60,8 +60,9 @@ func readDappActionFromProto(protoContent, actionName string) ([]*actionInfoItem
func formatExecContent(infos []*actionInfoItem, dappName string) string { func formatExecContent(infos []*actionInfoItem, dappName string) string {
fnFmtStr := `func (c *%s) Exec_%s(payload *ptypes.%s, tx *types.Transaction, index int) (*types.Receipt, error) { fnFmtStr := `func (c *%s) Exec_%s(payload *ptypes.%s, tx *types.Transaction, index int) (*types.Receipt, error) {
var receipt *types.Receipt
//implement code //implement code
return &types.Receipt{}, nil return receipt, nil
} }
` `
...@@ -76,8 +77,9 @@ func formatExecContent(infos []*actionInfoItem, dappName string) string { ...@@ -76,8 +77,9 @@ func formatExecContent(infos []*actionInfoItem, dappName string) string {
func formatExecLocalContent(infos []*actionInfoItem, dappName string) string { func formatExecLocalContent(infos []*actionInfoItem, dappName string) string {
fnFmtStr := `func (c *%s) ExecLocal_%s(payload *ptypes.%s, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) { fnFmtStr := `func (c *%s) ExecLocal_%s(payload *ptypes.%s, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
var dbSet *types.LocalDBSet
//implement code //implement code
return &types.LocalDBSet{}, nil return dbSet, nil
} }
` `
...@@ -92,8 +94,9 @@ func formatExecLocalContent(infos []*actionInfoItem, dappName string) string { ...@@ -92,8 +94,9 @@ func formatExecLocalContent(infos []*actionInfoItem, dappName string) string {
func formatExecDelLocalContent(infos []*actionInfoItem, dappName string) string { func formatExecDelLocalContent(infos []*actionInfoItem, dappName string) string {
fnFmtStr := `func (c *%s) ExecDelLocal_%s(payload *ptypes.%s, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) { fnFmtStr := `func (c *%s) ExecDelLocal_%s(payload *ptypes.%s, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
var dbSet *types.LocalDBSet
//implement code //implement code
return &types.LocalDBSet{}, nil return dbSet, nil
} }
` `
...@@ -107,9 +110,9 @@ func formatExecDelLocalContent(infos []*actionInfoItem, dappName string) string ...@@ -107,9 +110,9 @@ func formatExecDelLocalContent(infos []*actionInfoItem, dappName string) string
// 组成规则是 TyLog+ActionName + ActionMemberName // 组成规则是 TyLog+ActionName + ActionMemberName
func buildActionLogTypeText(infos []*actionInfoItem, className string) (text string) { func buildActionLogTypeText(infos []*actionInfoItem, className string) (text string) {
items := fmt.Sprintf("TyLog%sUnknown = iota\n", className) items := fmt.Sprintf("TyUnknownLog = iota + 100\n")
for _, info := range infos { for _, info := range infos {
items += fmt.Sprintf("TyLog%s%s\n", className, info.memberName) items += fmt.Sprintf("Ty%sLog\n", info.memberName)
} }
text = fmt.Sprintf("const (\n%s)\n", items) text = fmt.Sprintf("const (\n%s)\n", items)
return return
...@@ -117,10 +120,16 @@ func buildActionLogTypeText(infos []*actionInfoItem, className string) (text str ...@@ -117,10 +120,16 @@ func buildActionLogTypeText(infos []*actionInfoItem, className string) (text str
// 组成规则是 ActionName + ActionMemberName // 组成规则是 ActionName + ActionMemberName
func buildActionIDText(infos []*actionInfoItem, className string) (text string) { func buildActionIDText(infos []*actionInfoItem, className string) (text string) {
var items string
for index, info := range infos { items := fmt.Sprintf("TyUnknowAction = iota + 100\n")
items += fmt.Sprintf("%sAction%s = %d\n", className, info.memberName, index) for _, info := range infos {
items += fmt.Sprintf("Ty%sAction\n", info.memberName)
} }
items += "\n"
for _, info := range infos {
items += fmt.Sprintf("Name%sAction = \"%s\"\n", info.memberName, info.memberName)
}
text = fmt.Sprintf("const (\n%s)\n", items) text = fmt.Sprintf("const (\n%s)\n", items)
return return
} }
...@@ -129,7 +138,7 @@ func buildActionIDText(infos []*actionInfoItem, className string) (text string) ...@@ -129,7 +138,7 @@ func buildActionIDText(infos []*actionInfoItem, className string) (text string)
func buildTypeMapText(infos []*actionInfoItem, className string) (text string) { func buildTypeMapText(infos []*actionInfoItem, className string) (text string) {
var items string var items string
for _, info := range infos { for _, info := range infos {
items += fmt.Sprintf("\"%s\": %sAction%s,\n", info.memberName, className, info.memberName) items += fmt.Sprintf("Name%sAction: Ty%sAction,\n", info.memberName, info.memberName)
} }
text = fmt.Sprintf("map[string]int32{\n%s}", items) text = fmt.Sprintf("map[string]int32{\n%s}", items)
return return
...@@ -137,6 +146,6 @@ func buildTypeMapText(infos []*actionInfoItem, className string) (text string) { ...@@ -137,6 +146,6 @@ func buildTypeMapText(infos []*actionInfoItem, className string) (text string) {
// 返回 map[string]*types.LogInfo // 返回 map[string]*types.LogInfo
func buildLogMapText() (text string) { func buildLogMapText() (text string) {
text = fmt.Sprintf("map[int64]*types.LogInfo{\n\t//pseudo code\n\t//LogID: {Ty: refelct.TypeOf(LogStruct), Name: LogName},\n}") text = fmt.Sprintf("map[int64]*types.LogInfo{\n\t//LogID: {Ty: reflect.TypeOf(LogStruct), Name: LogName},\n}")
return return
} }
...@@ -203,7 +203,7 @@ func (e *executor) Exec(tx *types.Transaction, index int) (*types.Receipt, error ...@@ -203,7 +203,7 @@ func (e *executor) Exec(tx *types.Transaction, index int) (*types.Receipt, error
if err := drivers.CheckAddress(tx.GetRealToAddr(), e.height); err != nil { if err := drivers.CheckAddress(tx.GetRealToAddr(), e.height); err != nil {
return nil, err return nil, err
} }
if e.localDB != nil { if e.localDB != nil && types.IsFork(e.height, "ForkLocalDBAccess") {
e.localDB.(*LocalDB).DisableWrite() e.localDB.(*LocalDB).DisableWrite()
if exec.ExecutorOrder() != drivers.ExecLocalSameTime { if exec.ExecutorOrder() != drivers.ExecLocalSameTime {
e.localDB.(*LocalDB).DisableRead() e.localDB.(*LocalDB).DisableRead()
......
...@@ -10,7 +10,6 @@ import ( ...@@ -10,7 +10,6 @@ import (
"strings" "strings"
"sync" "sync"
"github.com/33cn/chain33/account"
"github.com/33cn/chain33/client/api" "github.com/33cn/chain33/client/api"
dbm "github.com/33cn/chain33/common/db" dbm "github.com/33cn/chain33/common/db"
clog "github.com/33cn/chain33/common/log" clog "github.com/33cn/chain33/common/log"
...@@ -26,7 +25,7 @@ import ( ...@@ -26,7 +25,7 @@ import (
) )
var elog = log.New("module", "execs") var elog = log.New("module", "execs")
var coinsAccount = account.NewCoinsAccount() var coinsAccount *dbm.DB
// SetLogLevel set log level // SetLogLevel set log level
func SetLogLevel(level string) { func SetLogLevel(level string) {
......
...@@ -1184,3 +1184,12 @@ func fmtAccount(balances []*types.Account) []*rpctypes.Account { ...@@ -1184,3 +1184,12 @@ func fmtAccount(balances []*types.Account) []*rpctypes.Account {
} }
return accounts return accounts
} }
// GetCoinSymbol get coin symbol
func (c *Chain33) GetCoinSymbol(in types.ReqNil, result *interface{}) error {
symbol := types.GetCoinSymbol()
resp := types.ReplyString{Data: symbol}
log.Warn("GetCoinSymbol", "Symbol", symbol)
*result = &resp
return nil
}
...@@ -140,7 +140,7 @@ func (c *CoinsType) GetAssets(tx *types.Transaction) ([]*types.Asset, error) { ...@@ -140,7 +140,7 @@ func (c *CoinsType) GetAssets(tx *types.Transaction) ([]*types.Asset, error) {
return nil, err return nil, err
} }
if assetlist[0].Symbol == "" { if assetlist[0].Symbol == "" {
assetlist[0].Symbol = types.BTY assetlist[0].Symbol = types.GetCoinSymbol()
} }
return assetlist, nil return assetlist, nil
} }
...@@ -22,6 +22,7 @@ type Config struct { ...@@ -22,6 +22,7 @@ type Config struct {
Pprof *Pprof `protobuf:"bytes,14,opt,name=pprof" json:"pprof,omitempty"` Pprof *Pprof `protobuf:"bytes,14,opt,name=pprof" json:"pprof,omitempty"`
Fork *ForkList `protobuf:"bytes,15,opt,name=fork" json:"fork,omitempty"` Fork *ForkList `protobuf:"bytes,15,opt,name=fork" json:"fork,omitempty"`
Health *HealthCheck `protobuf:"bytes,16,opt,name=health" json:"health,omitempty"` Health *HealthCheck `protobuf:"bytes,16,opt,name=health" json:"health,omitempty"`
CoinSymbol string `protobuf:"bytes,16,opt,name=coinSymbol" json:"coinSymbol,omitempty"`
} }
// ForkList fork列表配置 // ForkList fork列表配置
......
...@@ -28,6 +28,7 @@ var ( ...@@ -28,6 +28,7 @@ var (
titles = map[string]bool{} titles = map[string]bool{}
chainConfig = make(map[string]interface{}) chainConfig = make(map[string]interface{})
mver = make(map[string]*mversion) mver = make(map[string]*mversion)
coinSymbol = "bty"
) )
// coin conversation // coin conversation
...@@ -247,6 +248,7 @@ func Init(t string, cfg *Config) { ...@@ -247,6 +248,7 @@ func Init(t string, cfg *Config) {
} }
titles[t] = true titles[t] = true
title = t title = t
if cfg != nil { if cfg != nil {
if isLocal() { if isLocal() {
setTestNet(true) setTestNet(true)
...@@ -264,6 +266,12 @@ func Init(t string, cfg *Config) { ...@@ -264,6 +266,12 @@ func Init(t string, cfg *Config) {
if cfg.Exec.MaxExecFee > 0 { if cfg.Exec.MaxExecFee > 0 {
setChainConfig("MaxFee", cfg.Exec.MaxExecFee) setChainConfig("MaxFee", cfg.Exec.MaxExecFee)
} }
if cfg.CoinSymbol != "" {
if strings.Contains(cfg.CoinSymbol, "-") {
panic("config CoinSymbol must without '-'")
}
coinSymbol = cfg.CoinSymbol
}
} }
//local 只用于单元测试 //local 只用于单元测试
if isLocal() { if isLocal() {
...@@ -301,6 +309,14 @@ func GetTitle() string { ...@@ -301,6 +309,14 @@ func GetTitle() string {
return s return s
} }
// GetCoinSymbol 获取 coin symbol
func GetCoinSymbol() string {
mu.Lock()
s := coinSymbol
mu.Unlock()
return s
}
func isLocal() bool { func isLocal() bool {
return title == "local" return title == "local"
} }
......
...@@ -100,6 +100,7 @@ driver="leveldb" ...@@ -100,6 +100,7 @@ driver="leveldb"
[mempool] [mempool]
poolCacheSize=102400 poolCacheSize=102400
minTxFee=100000 minTxFee=100000
maxTxFee=1000000000
[consensus] [consensus]
name="ticket" name="ticket"
...@@ -186,6 +187,7 @@ signType="secp256k1" ...@@ -186,6 +187,7 @@ signType="secp256k1"
[exec] [exec]
isFree=false isFree=false
minExecFee=100000 minExecFee=100000
maxExecFee=1000000000
[exec.sub.token] [exec.sub.token]
#配置一个空值,防止配置文件被覆盖 #配置一个空值,防止配置文件被覆盖
...@@ -219,6 +221,7 @@ ForkTxHeight= -1 ...@@ -219,6 +221,7 @@ ForkTxHeight= -1
ForkTxGroupPara= -1 ForkTxGroupPara= -1
ForkChainParamV2= -1 ForkChainParamV2= -1
ForkBlockCheck=1725000 ForkBlockCheck=1725000
ForkLocalDBAccess=1
[fork.sub.coins] [fork.sub.coins]
Enable=0 Enable=0
......
...@@ -210,8 +210,9 @@ func SetTestNetFork() { ...@@ -210,8 +210,9 @@ func SetTestNetFork() {
systemFork.SetFork("chain33", "ForkTxGroupPara", 806578) systemFork.SetFork("chain33", "ForkTxGroupPara", 806578)
systemFork.SetFork("chain33", "ForkCheckBlockTime", 1200000) systemFork.SetFork("chain33", "ForkCheckBlockTime", 1200000)
systemFork.SetFork("chain33", "ForkMultiSignAddress", 1298600) systemFork.SetFork("chain33", "ForkMultiSignAddress", 1298600)
systemFork.SetFork("chain33", "ForkStateDBSet", MaxHeight) systemFork.SetFork("chain33", "ForkStateDBSet", 1572391)
systemFork.SetFork("chain33", "ForkBlockCheck", 1560000) systemFork.SetFork("chain33", "ForkBlockCheck", 1560000)
systemFork.SetFork("chain33", "ForkLocalDBAccess", 1572391)
} }
func setLocalFork() { func setLocalFork() {
......
...@@ -173,6 +173,7 @@ ForkTxGroupPara= -1 ...@@ -173,6 +173,7 @@ ForkTxGroupPara= -1
ForkCheckBlockTime=1200000 ForkCheckBlockTime=1200000
ForkMultiSignAddress=1298600 ForkMultiSignAddress=1298600
ForkBlockCheck=1725000 ForkBlockCheck=1725000
ForkLocalDBAccess=1
[fork.sub.coins] [fork.sub.coins]
Enable=0 Enable=0
......
...@@ -189,6 +189,7 @@ ForkTxGroupPara= -1 ...@@ -189,6 +189,7 @@ ForkTxGroupPara= -1
ForkCheckBlockTime=1200000 ForkCheckBlockTime=1200000
ForkMultiSignAddress=1298600 ForkMultiSignAddress=1298600
ForkBlockCheck=1 ForkBlockCheck=1
ForkLocalDBAccess=0
[fork.sub.coins] [fork.sub.coins]
Enable=0 Enable=0
......
...@@ -105,7 +105,7 @@ func (s *HealthCheckServer) getHealth(sync bool) (bool, error) { ...@@ -105,7 +105,7 @@ func (s *HealthCheckServer) getHealth(sync bool) (bool, error) {
return false, err return false, err
} }
log.Info("healthCheck tick", "peers", len(peerList.Peers), "isCaughtUp", reply.IsOk, log.Debug("healthCheck tick", "peers", len(peerList.Peers), "isCaughtUp", reply.IsOk,
"health", len(peerList.Peers) > 1 && reply.IsOk, "listen", sync) "health", len(peerList.Peers) > 1 && reply.IsOk, "listen", sync)
return len(peerList.Peers) > 1 && reply.IsOk, nil return len(peerList.Peers) > 1 && reply.IsOk, nil
......
...@@ -20,8 +20,8 @@ func TestStart(t *testing.T) { ...@@ -20,8 +20,8 @@ func TestStart(t *testing.T) {
health := NewHealthCheckServer(q.Client()) health := NewHealthCheckServer(q.Client())
api := new(mocks.QueueProtocolAPI) api := new(mocks.QueueProtocolAPI)
reply := &types.Reply{IsOk: true} api.On("IsSync").Return(&types.Reply{IsOk: true}, nil).Times(2)
api.On("IsSync").Return(reply, nil) api.On("IsSync").Return(&types.Reply{IsOk: false}, nil)
peer1 := &types.Peer{Addr: "addr1"} peer1 := &types.Peer{Addr: "addr1"}
peer2 := &types.Peer{Addr: "addr2"} peer2 := &types.Peer{Addr: "addr2"}
peers := &types.PeerList{Peers: []*types.Peer{peer1, peer2}} peers := &types.PeerList{Peers: []*types.Peer{peer1, peer2}}
...@@ -31,12 +31,11 @@ func TestStart(t *testing.T) { ...@@ -31,12 +31,11 @@ func TestStart(t *testing.T) {
cfg, _ := types.InitCfg("../cmd/chain33/chain33.test.toml") cfg, _ := types.InitCfg("../cmd/chain33/chain33.test.toml")
health.Start(cfg.Health) health.Start(cfg.Health)
time.Sleep(time.Second * 3) time.Sleep(time.Second * 6)
api.On("IsSync").Return(&types.Reply{IsOk: false}, nil)
health.Start(cfg.Health)
time.Sleep(time.Second * 3)
health.Close() health.Close()
time.Sleep(time.Second * 1) time.Sleep(time.Second * 1)
} }
func TestGetHealth(t *testing.T) { func TestGetHealth(t *testing.T) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment