Commit 88db31ff authored by vipwzw's avatar vipwzw

update chain33 master

parent cf38751f
...@@ -10,6 +10,8 @@ datadir* ...@@ -10,6 +10,8 @@ datadir*
.idea .idea
.vscode .vscode
cmd/chain33/chain33 cmd/chain33/chain33
build/cert.pem
build/key.pem
build/chain33* build/chain33*
build/datadir build/datadir
build/bityuan* build/bityuan*
......
...@@ -195,6 +195,16 @@ func (bs *BlockStore) initQuickIndex(height int64) { ...@@ -195,6 +195,16 @@ func (bs *BlockStore) initQuickIndex(height int64) {
bs.saveQuickIndexFlag() bs.saveQuickIndexFlag()
} }
func (bs *BlockStore) isSeqCBExist(name string) bool {
value, err := bs.db.Get(calcSeqCBKey([]byte(name)))
if err == nil {
var cb types.BlockSeqCB
err = types.Decode(value, &cb)
return err == nil
}
return false
}
func (bs *BlockStore) seqCBNum() int64 { func (bs *BlockStore) seqCBNum() int64 {
counts := dbm.NewListHelper(bs.db).PrefixCount(seqCBPrefix) counts := dbm.NewListHelper(bs.db).PrefixCount(seqCBPrefix)
return counts return counts
...@@ -204,6 +214,8 @@ func (bs *BlockStore) addBlockSeqCB(cb *types.BlockSeqCB) error { ...@@ -204,6 +214,8 @@ func (bs *BlockStore) addBlockSeqCB(cb *types.BlockSeqCB) error {
if len(cb.Name) > 128 || len(cb.URL) > 1024 { if len(cb.Name) > 128 || len(cb.URL) > 1024 {
return types.ErrInvalidParam return types.ErrInvalidParam
} }
storeLog.Info("addBlockSeqCB", "key", string(calcSeqCBKey([]byte(cb.Name))), "value", cb)
return bs.db.SetSync(calcSeqCBKey([]byte(cb.Name)), types.Encode(cb)) return bs.db.SetSync(calcSeqCBKey([]byte(cb.Name)), types.Encode(cb))
} }
...@@ -461,9 +473,9 @@ func (bs *BlockStore) LoadBlockByHash(hash []byte) (*types.BlockDetail, error) { ...@@ -461,9 +473,9 @@ func (bs *BlockStore) LoadBlockByHash(hash []byte) (*types.BlockDetail, error) {
return &blockdetail, nil return &blockdetail, nil
} }
//SaveBlock 批量保存blocks信息到db数据库中 //SaveBlock 批量保存blocks信息到db数据库中,并返回最新的sequence值
func (bs *BlockStore) SaveBlock(storeBatch dbm.Batch, blockdetail *types.BlockDetail, sequence int64) error { func (bs *BlockStore) SaveBlock(storeBatch dbm.Batch, blockdetail *types.BlockDetail, sequence int64) (int64, error) {
var lastSequence int64 = -1
height := blockdetail.Block.Height height := blockdetail.Block.Height
if len(blockdetail.Receipts) == 0 && len(blockdetail.Block.Txs) != 0 { if len(blockdetail.Receipts) == 0 && len(blockdetail.Block.Txs) != 0 {
storeLog.Error("SaveBlock Receipts is nil ", "height", height) storeLog.Error("SaveBlock Receipts is nil ", "height", height)
...@@ -478,7 +490,7 @@ func (bs *BlockStore) SaveBlock(storeBatch dbm.Batch, blockdetail *types.BlockDe ...@@ -478,7 +490,7 @@ func (bs *BlockStore) SaveBlock(storeBatch dbm.Batch, blockdetail *types.BlockDe
body, err := proto.Marshal(&blockbody) body, err := proto.Marshal(&blockbody)
if err != nil { if err != nil {
storeLog.Error("SaveBlock Marshal blockbody", "height", height, "hash", common.ToHex(hash), "error", err) storeLog.Error("SaveBlock Marshal blockbody", "height", height, "hash", common.ToHex(hash), "error", err)
return err return lastSequence, err
} }
storeBatch.Set(calcHashToBlockBodyKey(hash), body) storeBatch.Set(calcHashToBlockBodyKey(hash), body)
...@@ -499,7 +511,7 @@ func (bs *BlockStore) SaveBlock(storeBatch dbm.Batch, blockdetail *types.BlockDe ...@@ -499,7 +511,7 @@ func (bs *BlockStore) SaveBlock(storeBatch dbm.Batch, blockdetail *types.BlockDe
header, err := proto.Marshal(&blockheader) header, err := proto.Marshal(&blockheader)
if err != nil { if err != nil {
storeLog.Error("SaveBlock Marshal blockheader", "height", height, "hash", common.ToHex(hash), "error", err) storeLog.Error("SaveBlock Marshal blockheader", "height", height, "hash", common.ToHex(hash), "error", err)
return err return lastSequence, err
} }
storeBatch.Set(calcHashToBlockHeaderKey(hash), header) storeBatch.Set(calcHashToBlockHeaderKey(hash), header)
...@@ -517,19 +529,19 @@ func (bs *BlockStore) SaveBlock(storeBatch dbm.Batch, blockdetail *types.BlockDe ...@@ -517,19 +529,19 @@ func (bs *BlockStore) SaveBlock(storeBatch dbm.Batch, blockdetail *types.BlockDe
if isRecordBlockSequence || isParaChain { if isRecordBlockSequence || isParaChain {
//存储记录block序列执行的type add //存储记录block序列执行的type add
err = bs.saveBlockSequence(storeBatch, hash, height, AddBlock, sequence) lastSequence, err = bs.saveBlockSequence(storeBatch, hash, height, AddBlock, sequence)
if err != nil { if err != nil {
storeLog.Error("SaveBlock SaveBlockSequence", "height", height, "hash", common.ToHex(hash), "error", err) storeLog.Error("SaveBlock SaveBlockSequence", "height", height, "hash", common.ToHex(hash), "error", err)
return err return lastSequence, err
} }
} }
storeLog.Debug("SaveBlock success", "blockheight", height, "hash", common.ToHex(hash)) storeLog.Debug("SaveBlock success", "blockheight", height, "hash", common.ToHex(hash))
return nil return lastSequence, nil
} }
//DelBlock 删除block信息从db数据库中 //DelBlock 删除block信息从db数据库中
func (bs *BlockStore) DelBlock(storeBatch dbm.Batch, blockdetail *types.BlockDetail, sequence int64) error { func (bs *BlockStore) DelBlock(storeBatch dbm.Batch, blockdetail *types.BlockDetail, sequence int64) (int64, error) {
var lastSequence int64 = -1
height := blockdetail.Block.Height height := blockdetail.Block.Height
hash := blockdetail.Block.Hash() hash := blockdetail.Block.Hash()
...@@ -546,15 +558,15 @@ func (bs *BlockStore) DelBlock(storeBatch dbm.Batch, blockdetail *types.BlockDet ...@@ -546,15 +558,15 @@ func (bs *BlockStore) DelBlock(storeBatch dbm.Batch, blockdetail *types.BlockDet
if isRecordBlockSequence || isParaChain { if isRecordBlockSequence || isParaChain {
//存储记录block序列执行的type del //存储记录block序列执行的type del
err := bs.saveBlockSequence(storeBatch, hash, height, DelBlock, sequence) lastSequence, err := bs.saveBlockSequence(storeBatch, hash, height, DelBlock, sequence)
if err != nil { if err != nil {
storeLog.Error("DelBlock SaveBlockSequence", "height", height, "hash", common.ToHex(hash), "error", err) storeLog.Error("DelBlock SaveBlockSequence", "height", height, "hash", common.ToHex(hash), "error", err)
return err return lastSequence, err
} }
} }
storeLog.Debug("DelBlock success", "blockheight", height, "hash", common.ToHex(hash)) storeLog.Debug("DelBlock success", "blockheight", height, "hash", common.ToHex(hash))
return nil return lastSequence, nil
} }
//GetTx 通过tx hash 从db数据库中获取tx交易信息 //GetTx 通过tx hash 从db数据库中获取tx交易信息
...@@ -874,25 +886,28 @@ func (bs *BlockStore) setSeqCBLastNum(name []byte, num int64) error { ...@@ -874,25 +886,28 @@ func (bs *BlockStore) setSeqCBLastNum(name []byte, num int64) error {
return bs.db.SetSync(caclSeqCBLastNumKey(name), types.Encode(&types.Int64{Data: num})) return bs.db.SetSync(caclSeqCBLastNumKey(name), types.Encode(&types.Int64{Data: num}))
} }
//Seq的合法值从0开始的,所以没有获取到或者获取失败都应该返回-1
func (bs *BlockStore) getSeqCBLastNum(name []byte) int64 { func (bs *BlockStore) getSeqCBLastNum(name []byte) int64 {
bytes, err := bs.db.Get(caclSeqCBLastNumKey(name)) bytes, err := bs.db.Get(caclSeqCBLastNumKey(name))
if bytes == nil || err != nil { if bytes == nil || err != nil {
if err != dbm.ErrNotFoundInDb { if err != dbm.ErrNotFoundInDb {
return -1 storeLog.Error("getSeqCBLastNum", "error", err)
} }
return 0 return -1
} }
n, err := decodeHeight(bytes) n, err := decodeHeight(bytes)
if err != nil { if err != nil {
return 0 return -1
} }
storeLog.Error("getSeqCBLastNum", "name", string(name), "num", n)
return n return n
} }
//SaveBlockSequence 存储block 序列执行的类型用于blockchain的恢复 //SaveBlockSequence 存储block 序列执行的类型用于blockchain的恢复
//获取当前的序列号,将此序列号加1存储本block的hash ,当主链使能isRecordBlockSequence //获取当前的序列号,将此序列号加1存储本block的hash ,当主链使能isRecordBlockSequence
// 平行链使能isParaChain时,sequence序列号是传入的 // 平行链使能isParaChain时,sequence序列号是传入的
func (bs *BlockStore) saveBlockSequence(storeBatch dbm.Batch, hash []byte, height int64, Type int64, sequence int64) error { func (bs *BlockStore) saveBlockSequence(storeBatch dbm.Batch, hash []byte, height int64, Type int64, sequence int64) (int64, error) {
var blockSequence types.BlockSequence var blockSequence types.BlockSequence
var newSequence int64 var newSequence int64
...@@ -921,7 +936,7 @@ func (bs *BlockStore) saveBlockSequence(storeBatch dbm.Batch, hash []byte, heigh ...@@ -921,7 +936,7 @@ func (bs *BlockStore) saveBlockSequence(storeBatch dbm.Batch, hash []byte, heigh
BlockSequenceByte, err := proto.Marshal(&blockSequence) BlockSequenceByte, err := proto.Marshal(&blockSequence)
if err != nil { if err != nil {
storeLog.Error("SaveBlockSequence Marshal BlockSequence", "hash", common.ToHex(hash), "error", err) storeLog.Error("SaveBlockSequence Marshal BlockSequence", "hash", common.ToHex(hash), "error", err)
return err return newSequence, err
} }
// seq->hash // seq->hash
...@@ -935,7 +950,7 @@ func (bs *BlockStore) saveBlockSequence(storeBatch dbm.Batch, hash []byte, heigh ...@@ -935,7 +950,7 @@ func (bs *BlockStore) saveBlockSequence(storeBatch dbm.Batch, hash []byte, heigh
Sequencebytes := types.Encode(&types.Int64{Data: newSequence}) Sequencebytes := types.Encode(&types.Int64{Data: newSequence})
storeBatch.Set(LastSequence, Sequencebytes) storeBatch.Set(LastSequence, Sequencebytes)
return nil return newSequence, nil
} }
//LoadBlockBySequence 通过seq高度获取BlockDetail信息 //LoadBlockBySequence 通过seq高度获取BlockDetail信息
......
...@@ -112,7 +112,7 @@ func TestBlockChain(t *testing.T) { ...@@ -112,7 +112,7 @@ func TestBlockChain(t *testing.T) {
testRemoveOrphanBlock(t, blockchain) testRemoveOrphanBlock(t, blockchain)
testLoadBlockBySequence(t, blockchain) testLoadBlockBySequence(t, blockchain)
testAddBlockSeqCB(t, blockchain)
testProcDelParaChainBlockMsg(t, mock33, blockchain) testProcDelParaChainBlockMsg(t, mock33, blockchain)
testProcAddParaChainBlockMsg(t, mock33, blockchain) testProcAddParaChainBlockMsg(t, mock33, blockchain)
...@@ -901,3 +901,33 @@ func testProcBlockChainFork(t *testing.T, blockchain *blockchain.BlockChain) { ...@@ -901,3 +901,33 @@ func testProcBlockChainFork(t *testing.T, blockchain *blockchain.BlockChain) {
blockchain.ProcBlockChainFork(curheight-1, curheight+256, "self") blockchain.ProcBlockChainFork(curheight-1, curheight+256, "self")
chainlog.Info("testProcBlockChainFork end --------------------") chainlog.Info("testProcBlockChainFork end --------------------")
} }
func testAddBlockSeqCB(t *testing.T, blockchain *blockchain.BlockChain) {
chainlog.Info("testAddBlockSeqCB begin ---------------------")
cb := &types.BlockSeqCB{
Name: "test",
URL: "http://192.168.1.107:15760",
Encode: "json",
}
err := blockchain.ProcAddBlockSeqCB(cb)
require.NoError(t, err)
cbs, err := blockchain.ProcListBlockSeqCB()
require.NoError(t, err)
exist := false
for _, temcb := range cbs.Items {
if temcb.Name == cb.Name {
exist = true
}
}
if !exist {
t.Error("testAddBlockSeqCB listSeqCB fail", "cb", cb, "cbs", cbs)
}
num := blockchain.ProcGetSeqCBLastNum(cb.Name)
if num != -1 {
t.Error("testAddBlockSeqCB getSeqCBLastNum", "num", num, "name", cb.Name)
}
chainlog.Info("testAddBlockSeqCB end -------------------------")
}
...@@ -85,6 +85,12 @@ func (chain *BlockChain) ProcRecvMsg() { ...@@ -85,6 +85,12 @@ func (chain *BlockChain) ProcRecvMsg() {
go chain.processMsg(msg, reqnum, chain.localPrefixCount) go chain.processMsg(msg, reqnum, chain.localPrefixCount)
case types.EventAddBlockSeqCB: case types.EventAddBlockSeqCB:
go chain.processMsg(msg, reqnum, chain.addBlockSeqCB) go chain.processMsg(msg, reqnum, chain.addBlockSeqCB)
case types.EventListBlockSeqCB:
go chain.processMsg(msg, reqnum, chain.listBlockSeqCB)
case types.EventGetSeqCBLastNum:
go chain.processMsg(msg, reqnum, chain.getSeqCBLastNum)
default: default:
go chain.processMsg(msg, reqnum, chain.unknowMsg) go chain.processMsg(msg, reqnum, chain.unknowMsg)
} }
...@@ -96,18 +102,36 @@ func (chain *BlockChain) unknowMsg(msg queue.Message) { ...@@ -96,18 +102,36 @@ func (chain *BlockChain) unknowMsg(msg queue.Message) {
} }
func (chain *BlockChain) addBlockSeqCB(msg queue.Message) { func (chain *BlockChain) addBlockSeqCB(msg queue.Message) {
if chain.blockStore.seqCBNum() >= MaxSeqCB { reply := &types.Reply{
msg.Reply(chain.client.NewMessage("rpc", types.EventAddBlockSeqCB, types.ErrTooManySeqCB)) IsOk: true,
return
} }
cb := (msg.Data).(*types.BlockSeqCB) cb := (msg.Data).(*types.BlockSeqCB)
err := chain.blockStore.addBlockSeqCB(cb) err := chain.ProcAddBlockSeqCB(cb)
if err != nil { if err != nil {
msg.Reply(chain.client.NewMessage("rpc", types.EventAddBlockSeqCB, err)) reply.IsOk = false
reply.Msg = []byte(err.Error())
msg.Reply(chain.client.NewMessage("rpc", types.EventAddBlockSeqCB, reply))
return return
} }
chain.pushseq.addTask(cb) chain.pushseq.addTask(cb)
msg.ReplyErr("EventAddBlockSeqCB", nil) msg.Reply(chain.client.NewMessage("rpc", types.EventAddBlockSeqCB, reply))
}
func (chain *BlockChain) listBlockSeqCB(msg queue.Message) {
cbs, err := chain.ProcListBlockSeqCB()
if err != nil {
chainlog.Error("listBlockSeqCB", "err", err.Error())
msg.Reply(chain.client.NewMessage("rpc", types.EventListBlockSeqCB, err))
return
}
msg.Reply(chain.client.NewMessage("rpc", types.EventListBlockSeqCB, cbs))
}
func (chain *BlockChain) getSeqCBLastNum(msg queue.Message) {
data := (msg.Data).(*types.ReqString)
num := chain.ProcGetSeqCBLastNum(data.Data)
lastNum := &types.Int64{Data: num}
msg.Reply(chain.client.NewMessage("rpc", types.EventGetSeqCBLastNum, lastNum))
} }
func (chain *BlockChain) queryTx(msg queue.Message) { func (chain *BlockChain) queryTx(msg queue.Message) {
......
...@@ -274,7 +274,6 @@ func (b *BlockChain) connectBestChain(node *blockNode, block *types.BlockDetail) ...@@ -274,7 +274,6 @@ func (b *BlockChain) connectBestChain(node *blockNode, block *types.BlockDetail)
//将本block信息存储到数据库中,并更新bestchain的tip节点 //将本block信息存储到数据库中,并更新bestchain的tip节点
func (b *BlockChain) connectBlock(node *blockNode, blockdetail *types.BlockDetail) (*types.BlockDetail, error) { func (b *BlockChain) connectBlock(node *blockNode, blockdetail *types.BlockDetail) (*types.BlockDetail, error) {
//blockchain close 时不再处理block //blockchain close 时不再处理block
if atomic.LoadInt32(&b.isclosed) == 1 { if atomic.LoadInt32(&b.isclosed) == 1 {
return nil, types.ErrIsClosed return nil, types.ErrIsClosed
...@@ -293,6 +292,8 @@ func (b *BlockChain) connectBlock(node *blockNode, blockdetail *types.BlockDetai ...@@ -293,6 +292,8 @@ func (b *BlockChain) connectBlock(node *blockNode, blockdetail *types.BlockDetai
} }
var err error var err error
var lastSequence int64
block := blockdetail.Block block := blockdetail.Block
prevStateHash := b.bestChain.Tip().statehash prevStateHash := b.bestChain.Tip().statehash
//广播或者同步过来的blcok需要调用执行模块 //广播或者同步过来的blcok需要调用执行模块
...@@ -308,27 +309,25 @@ func (b *BlockChain) connectBlock(node *blockNode, blockdetail *types.BlockDetai ...@@ -308,27 +309,25 @@ func (b *BlockChain) connectBlock(node *blockNode, blockdetail *types.BlockDetai
} }
//要更新node的信息 //要更新node的信息
if node.pid == "self" { if node.pid == "self" {
//update node info
prevhash := node.hash prevhash := node.hash
node.statehash = blockdetail.Block.GetStateHash() node.statehash = blockdetail.Block.GetStateHash()
node.hash = blockdetail.Block.Hash() node.hash = blockdetail.Block.Hash()
b.index.UpdateNode(prevhash, node) b.index.UpdateNode(prevhash, node)
} }
beg := types.Now()
// 写入磁盘
//批量将block信息写入磁盘
beg := types.Now()
// 写入磁盘 批量将block信息写入磁盘
newbatch := b.blockStore.NewBatch(sync) newbatch := b.blockStore.NewBatch(sync)
//保存tx信息到db中 (newbatch, blockdetail)
//保存tx信息到db中
err = b.blockStore.AddTxs(newbatch, blockdetail) err = b.blockStore.AddTxs(newbatch, blockdetail)
if err != nil { if err != nil {
chainlog.Error("connectBlock indexTxs:", "height", block.Height, "err", err) chainlog.Error("connectBlock indexTxs:", "height", block.Height, "err", err)
return nil, err return nil, err
} }
//chainlog.Debug("connectBlock AddTxs!", "height", block.Height, "batchsync", sync)
//保存block信息到db中 //保存block信息到db中
err = b.blockStore.SaveBlock(newbatch, blockdetail, node.sequence) lastSequence, err = b.blockStore.SaveBlock(newbatch, blockdetail, node.sequence)
if err != nil { if err != nil {
chainlog.Error("connectBlock SaveBlock:", "height", block.Height, "err", err) chainlog.Error("connectBlock SaveBlock:", "height", block.Height, "err", err)
return nil, err return nil, err
...@@ -348,8 +347,6 @@ func (b *BlockChain) connectBlock(node *blockNode, blockdetail *types.BlockDetai ...@@ -348,8 +347,6 @@ func (b *BlockChain) connectBlock(node *blockNode, blockdetail *types.BlockDetai
return nil, err return nil, err
} }
blocktd = new(big.Int).Add(difficulty, parenttd) blocktd = new(big.Int).Add(difficulty, parenttd)
//chainlog.Error("connectBlock Difficulty", "height", block.Height, "parenttd.td", difficulty.BigToCompact(parenttd))
//chainlog.Error("connectBlock Difficulty", "height", block.Height, "self.td", difficulty.BigToCompact(blocktd))
} }
err = b.blockStore.SaveTdByBlockHash(newbatch, blockdetail.Block.Hash(), blocktd) err = b.blockStore.SaveTdByBlockHash(newbatch, blockdetail.Block.Hash(), blocktd)
...@@ -389,12 +386,16 @@ func (b *BlockChain) connectBlock(node *blockNode, blockdetail *types.BlockDetai ...@@ -389,12 +386,16 @@ func (b *BlockChain) connectBlock(node *blockNode, blockdetail *types.BlockDetai
b.SendBlockBroadcast(blockdetail) b.SendBlockBroadcast(blockdetail)
} }
} }
b.pushseq.updateSeq(node.sequence) //目前非平行链并开启isRecordBlockSequence功能
if isRecordBlockSequence && !isParaChain {
b.pushseq.updateSeq(lastSequence)
}
return blockdetail, nil return blockdetail, nil
} }
//从主链中删除blocks //从主链中删除blocks
func (b *BlockChain) disconnectBlock(node *blockNode, blockdetail *types.BlockDetail, sequence int64) error { func (b *BlockChain) disconnectBlock(node *blockNode, blockdetail *types.BlockDetail, sequence int64) error {
var lastSequence int64
// 只能从 best chain tip节点开始删除 // 只能从 best chain tip节点开始删除
if !bytes.Equal(node.hash, b.bestChain.Tip().hash) { if !bytes.Equal(node.hash, b.bestChain.Tip().hash) {
chainlog.Error("disconnectBlock:", "height", blockdetail.Block.Height, "node.hash", common.ToHex(node.hash), "bestChain.top.hash", common.ToHex(b.bestChain.Tip().hash)) chainlog.Error("disconnectBlock:", "height", blockdetail.Block.Height, "node.hash", common.ToHex(node.hash), "bestChain.top.hash", common.ToHex(b.bestChain.Tip().hash))
...@@ -412,7 +413,7 @@ func (b *BlockChain) disconnectBlock(node *blockNode, blockdetail *types.BlockDe ...@@ -412,7 +413,7 @@ func (b *BlockChain) disconnectBlock(node *blockNode, blockdetail *types.BlockDe
} }
//从db中删除block相关的信息 //从db中删除block相关的信息
err = b.blockStore.DelBlock(newbatch, blockdetail, sequence) lastSequence, err = b.blockStore.DelBlock(newbatch, blockdetail, sequence)
if err != nil { if err != nil {
chainlog.Error("disconnectBlock DelBlock:", "height", blockdetail.Block.Height, "err", err) chainlog.Error("disconnectBlock DelBlock:", "height", blockdetail.Block.Height, "err", err)
return err return err
...@@ -450,7 +451,11 @@ func (b *BlockChain) disconnectBlock(node *blockNode, blockdetail *types.BlockDe ...@@ -450,7 +451,11 @@ func (b *BlockChain) disconnectBlock(node *blockNode, blockdetail *types.BlockDe
chainlog.Debug("disconnectBlock success", "newtipnode.height", newtipnode.height, "node.parent.height", node.parent.height) chainlog.Debug("disconnectBlock success", "newtipnode.height", newtipnode.height, "node.parent.height", node.parent.height)
chainlog.Debug("disconnectBlock success", "newtipnode.hash", common.ToHex(newtipnode.hash), "delblock.parent.hash", common.ToHex(blockdetail.Block.GetParentHash())) chainlog.Debug("disconnectBlock success", "newtipnode.hash", common.ToHex(newtipnode.hash), "delblock.parent.hash", common.ToHex(blockdetail.Block.GetParentHash()))
b.pushseq.updateSeq(node.sequence)
//目前非平行链并开启isRecordBlockSequence功能
if isRecordBlockSequence && !isParaChain {
b.pushseq.updateSeq(lastSequence)
}
return nil return nil
} }
......
...@@ -11,6 +11,7 @@ import ( ...@@ -11,6 +11,7 @@ import (
"github.com/33cn/chain33/types" "github.com/33cn/chain33/types"
) )
//pushNotify push Notify
type pushNotify struct { type pushNotify struct {
cb chan *types.BlockSeqCB cb chan *types.BlockSeqCB
seq chan int64 seq chan int64
...@@ -41,13 +42,16 @@ func (p *pushseq) init() { ...@@ -41,13 +42,16 @@ func (p *pushseq) init() {
} }
} }
func (p *pushseq) updateLastSeq() { //只更新本cb的seq值,每次add一个新cb时如果刷新所有的cb,会耗时很长在初始化时
func (p *pushseq) updateLastSeq(name string) {
last, err := p.store.LoadBlockLastSequence() last, err := p.store.LoadBlockLastSequence()
if err != nil { if err != nil {
chainlog.Error("listSeqCB", "err", err) chainlog.Error("LoadBlockLastSequence", "err", err)
return return
} }
p.updateSeq(last)
notify := p.cmds[name]
notify.seq <- last
} }
//每个name 有一个task //每个name 有一个task
...@@ -57,6 +61,7 @@ func (p *pushseq) addTask(cb *types.BlockSeqCB) { ...@@ -57,6 +61,7 @@ func (p *pushseq) addTask(cb *types.BlockSeqCB) {
if notify, ok := p.cmds[cb.Name]; ok { if notify, ok := p.cmds[cb.Name]; ok {
notify.cb <- cb notify.cb <- cb
if cb.URL == "" { if cb.URL == "" {
chainlog.Debug("delete callback", "cb", cb)
delete(p.cmds, cb.Name) delete(p.cmds, cb.Name)
} }
return return
...@@ -67,14 +72,23 @@ func (p *pushseq) addTask(cb *types.BlockSeqCB) { ...@@ -67,14 +72,23 @@ func (p *pushseq) addTask(cb *types.BlockSeqCB) {
} }
p.cmds[cb.Name].cb <- cb p.cmds[cb.Name].cb <- cb
p.runTask(p.cmds[cb.Name]) p.runTask(p.cmds[cb.Name])
//更新最新的seq //更新最新的seq
p.updateLastSeq() p.updateLastSeq(cb.Name)
chainlog.Debug("runTask callback", "cb", cb)
} }
func (p *pushseq) updateSeq(seq int64) { func (p *pushseq) updateSeq(seq int64) {
p.mu.Lock() p.mu.Lock()
defer p.mu.Unlock() defer p.mu.Unlock()
for _, notify := range p.cmds { for _, notify := range p.cmds {
//如果有seq, 那么先读一个出来
select {
case <-notify.seq:
default:
}
//再写入seq(一定不会block,因为加了lock,不存在两个同时写channel的情况)
notify.seq <- seq notify.seq <- seq
} }
} }
...@@ -127,8 +141,8 @@ func (p *pushseq) runTask(input pushNotify) { ...@@ -127,8 +141,8 @@ func (p *pushseq) runTask(input pushNotify) {
err = p.postData(cb, data) err = p.postData(cb, data)
if err != nil { if err != nil {
chainlog.Error("postdata", "err", err) chainlog.Error("postdata", "err", err)
//sleep 10s //sleep 60s
p.trigeRun(run, 10000*time.Millisecond) p.trigeRun(run, 60000*time.Millisecond)
continue continue
} }
//update seqid //update seqid
...@@ -141,6 +155,7 @@ func (p *pushseq) runTask(input pushNotify) { ...@@ -141,6 +155,7 @@ func (p *pushseq) runTask(input pushNotify) {
func (p *pushseq) postData(cb *types.BlockSeqCB, data *types.BlockSeq) (err error) { func (p *pushseq) postData(cb *types.BlockSeqCB, data *types.BlockSeq) (err error) {
var postdata []byte var postdata []byte
if cb.Encode == "json" { if cb.Encode == "json" {
postdata, err = types.PBToJSON(data) postdata, err = types.PBToJSON(data)
if err != nil { if err != nil {
...@@ -149,6 +164,7 @@ func (p *pushseq) postData(cb *types.BlockSeqCB, data *types.BlockSeq) (err erro ...@@ -149,6 +164,7 @@ func (p *pushseq) postData(cb *types.BlockSeqCB, data *types.BlockSeq) (err erro
} else { } else {
postdata = types.Encode(data) postdata = types.Encode(data)
} }
//post data in body //post data in body
var buf bytes.Buffer var buf bytes.Buffer
g := gzip.NewWriter(&buf) g := gzip.NewWriter(&buf)
...@@ -163,6 +179,7 @@ func (p *pushseq) postData(cb *types.BlockSeqCB, data *types.BlockSeq) (err erro ...@@ -163,6 +179,7 @@ func (p *pushseq) postData(cb *types.BlockSeqCB, data *types.BlockSeq) (err erro
if err != nil { if err != nil {
return err return err
} }
req.Header.Set("Content-Type", "text/plain") req.Header.Set("Content-Type", "text/plain")
req.Header.Set("Content-Encoding", "gzip") req.Header.Set("Content-Encoding", "gzip")
resp, err := p.client.Do(req) resp, err := p.client.Do(req)
...@@ -175,8 +192,10 @@ func (p *pushseq) postData(cb *types.BlockSeqCB, data *types.BlockSeq) (err erro ...@@ -175,8 +192,10 @@ func (p *pushseq) postData(cb *types.BlockSeqCB, data *types.BlockSeq) (err erro
return err return err
} }
if string(body) != "ok" && string(body) != "OK" { if string(body) != "ok" && string(body) != "OK" {
chainlog.Error("postData fail", "cb.name", cb.Name, "body", string(body))
return types.ErrPushSeqPostData return types.ErrPushSeqPostData
} }
chainlog.Debug("postData success", "cb.name", cb.Name, "SeqNum", data.Num)
p.store.setSeqCBLastNum([]byte(cb.Name), data.Num) p.store.setSeqCBLastNum([]byte(cb.Name), data.Num)
return nil return nil
} }
......
...@@ -86,3 +86,40 @@ func (chain *BlockChain) ProcGetSeqByHash(hash []byte) (int64, error) { ...@@ -86,3 +86,40 @@ func (chain *BlockChain) ProcGetSeqByHash(hash []byte) (int64, error) {
return seq, err return seq, err
} }
//ProcAddBlockSeqCB 添加seq callback
func (chain *BlockChain) ProcAddBlockSeqCB(cb *types.BlockSeqCB) error {
if cb == nil {
return types.ErrInvalidParam
}
if chain.blockStore.seqCBNum() >= MaxSeqCB && !chain.blockStore.isSeqCBExist(cb.Name) {
return types.ErrTooManySeqCB
}
err := chain.blockStore.addBlockSeqCB(cb)
if err != nil {
return err
}
chain.pushseq.addTask(cb)
return nil
}
//ProcListBlockSeqCB 列出所有已经设置的seq callback
func (chain *BlockChain) ProcListBlockSeqCB() (*types.BlockSeqCBs, error) {
cbs, err := chain.blockStore.listSeqCB()
if err != nil {
chainlog.Error("ProcListBlockSeqCB", "err", err.Error())
return nil, err
}
var listSeqCBs types.BlockSeqCBs
listSeqCBs.Items = append(listSeqCBs.Items, cbs...)
return &listSeqCBs, nil
}
//ProcGetSeqCBLastNum 获取指定name的callback已经push的最新seq num
func (chain *BlockChain) ProcGetSeqCBLastNum(name string) int64 {
num := chain.blockStore.getSeqCBLastNum([]byte(name))
return num
}
...@@ -5,4 +5,6 @@ COPY chain33 chain33 ...@@ -5,4 +5,6 @@ COPY chain33 chain33
COPY chain33-cli chain33-cli COPY chain33-cli chain33-cli
COPY chain33.toml ./ COPY chain33.toml ./
RUN ./chain33-cli cert --host=127.0.0.1
CMD ["/root/chain33", "-f", "/root/chain33.toml"] CMD ["/root/chain33", "-f", "/root/chain33.toml"]
...@@ -11,6 +11,29 @@ type QueueProtocolAPI struct { ...@@ -11,6 +11,29 @@ type QueueProtocolAPI struct {
mock.Mock mock.Mock
} }
// AddSeqCallBack provides a mock function with given fields: param
func (_m *QueueProtocolAPI) AddSeqCallBack(param *types.BlockSeqCB) (*types.Reply, error) {
ret := _m.Called(param)
var r0 *types.Reply
if rf, ok := ret.Get(0).(func(*types.BlockSeqCB) *types.Reply); ok {
r0 = rf(param)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*types.Reply)
}
}
var r1 error
if rf, ok := ret.Get(1).(func(*types.BlockSeqCB) error); ok {
r1 = rf(param)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// Close provides a mock function with given fields: // Close provides a mock function with given fields:
func (_m *QueueProtocolAPI) Close() { func (_m *QueueProtocolAPI) Close() {
_m.Called() _m.Called()
...@@ -453,6 +476,29 @@ func (_m *QueueProtocolAPI) GetSeed(param *types.GetSeedByPw) (*types.ReplySeed, ...@@ -453,6 +476,29 @@ func (_m *QueueProtocolAPI) GetSeed(param *types.GetSeedByPw) (*types.ReplySeed,
return r0, r1 return r0, r1
} }
// GetSeqCallBackLastNum provides a mock function with given fields: param
func (_m *QueueProtocolAPI) GetSeqCallBackLastNum(param *types.ReqString) (*types.Int64, error) {
ret := _m.Called(param)
var r0 *types.Int64
if rf, ok := ret.Get(0).(func(*types.ReqString) *types.Int64); ok {
r0 = rf(param)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*types.Int64)
}
}
var r1 error
if rf, ok := ret.Get(1).(func(*types.ReqString) error); ok {
r1 = rf(param)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// GetTransactionByAddr provides a mock function with given fields: param // GetTransactionByAddr provides a mock function with given fields: param
func (_m *QueueProtocolAPI) GetTransactionByAddr(param *types.ReqAddr) (*types.ReplyTxInfos, error) { func (_m *QueueProtocolAPI) GetTransactionByAddr(param *types.ReqAddr) (*types.ReplyTxInfos, error) {
ret := _m.Called(param) ret := _m.Called(param)
...@@ -591,6 +637,29 @@ func (_m *QueueProtocolAPI) IsSync() (*types.Reply, error) { ...@@ -591,6 +637,29 @@ func (_m *QueueProtocolAPI) IsSync() (*types.Reply, error) {
return r0, r1 return r0, r1
} }
// ListSeqCallBack provides a mock function with given fields:
func (_m *QueueProtocolAPI) ListSeqCallBack() (*types.BlockSeqCBs, error) {
ret := _m.Called()
var r0 *types.BlockSeqCBs
if rf, ok := ret.Get(0).(func() *types.BlockSeqCBs); ok {
r0 = rf()
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*types.BlockSeqCBs)
}
}
var r1 error
if rf, ok := ret.Get(1).(func() error); ok {
r1 = rf()
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// LocalGet provides a mock function with given fields: param // LocalGet provides a mock function with given fields: param
func (_m *QueueProtocolAPI) LocalGet(param *types.LocalDBGet) (*types.LocalReplyValue, error) { func (_m *QueueProtocolAPI) LocalGet(param *types.LocalDBGet) (*types.LocalReplyValue, error) {
ret := _m.Called(param) ret := _m.Called(param)
......
...@@ -983,3 +983,45 @@ func (q *QueueProtocol) GetTicketCount() (*types.Int64, error) { ...@@ -983,3 +983,45 @@ func (q *QueueProtocol) GetTicketCount() (*types.Int64, error) {
} }
return nil, types.ErrTypeAsset return nil, types.ErrTypeAsset
} }
// AddSeqCallBack Add Seq CallBack
func (q *QueueProtocol) AddSeqCallBack(param *types.BlockSeqCB) (*types.Reply, error) {
msg, err := q.query(blockchainKey, types.EventAddBlockSeqCB, param)
if err != nil {
log.Error("AddSeqCallBack", "Error", err.Error())
return nil, err
}
if reply, ok := msg.GetData().(*types.Reply); ok {
return reply, nil
}
return nil, types.ErrTypeAsset
}
// ListSeqCallBack List Seq CallBacks
func (q *QueueProtocol) ListSeqCallBack() (*types.BlockSeqCBs, error) {
msg, err := q.query(blockchainKey, types.EventListBlockSeqCB, &types.ReqNil{})
if err != nil {
log.Error("ListSeqCallBack", "Error", err.Error())
return nil, err
}
if reply, ok := msg.GetData().(*types.BlockSeqCBs); ok {
return reply, nil
}
return nil, types.ErrTypeAsset
}
// GetSeqCallBackLastNum Get Seq Call Back Last Num
func (q *QueueProtocol) GetSeqCallBackLastNum(param *types.ReqString) (*types.Int64, error) {
msg, err := q.query(blockchainKey, types.EventGetSeqCBLastNum, param)
if err != nil {
log.Error("ListSeqCallBack", "Error", err.Error())
return nil, err
}
if reply, ok := msg.GetData().(*types.Int64); ok {
return reply, nil
}
return nil, types.ErrTypeAsset
}
...@@ -124,4 +124,11 @@ type QueueProtocolAPI interface { ...@@ -124,4 +124,11 @@ type QueueProtocolAPI interface {
// close chain33 // close chain33
CloseQueue() (*types.Reply, error) CloseQueue() (*types.Reply, error)
// --------------- other interfaces end // --------------- other interfaces end
// types.EventAddBlockSeqCB
AddSeqCallBack(param *types.BlockSeqCB) (*types.Reply, error)
// types.EventListBlockSeqCB
ListSeqCallBack() (*types.BlockSeqCBs, error)
// types.EventGetSeqCBLastNum
GetSeqCallBackLastNum(param *types.ReqString) (*types.Int64, error)
} }
...@@ -46,6 +46,9 @@ grpcBindAddr="localhost:8802" ...@@ -46,6 +46,9 @@ grpcBindAddr="localhost:8802"
whitelist=["127.0.0.1"] whitelist=["127.0.0.1"]
jrpcFuncWhitelist=["*"] jrpcFuncWhitelist=["*"]
grpcFuncWhitelist=["*"] grpcFuncWhitelist=["*"]
enableTLS=false
certFile="cert.pem"
keyFile="key.pem"
[mempool] [mempool]
maxTxNumPerAccount=100 maxTxNumPerAccount=100
......
...@@ -59,6 +59,9 @@ grpcBindAddr="localhost:8802" ...@@ -59,6 +59,9 @@ grpcBindAddr="localhost:8802"
whitelist=["127.0.0.1"] whitelist=["127.0.0.1"]
jrpcFuncWhitelist=["*"] jrpcFuncWhitelist=["*"]
grpcFuncWhitelist=["*"] grpcFuncWhitelist=["*"]
enableTLS=false
certFile="cert.pem"
keyFile="key.pem"
[mempool] [mempool]
poolCacheSize=10240 poolCacheSize=10240
......
...@@ -59,6 +59,9 @@ grpcBindAddr="localhost:8802" ...@@ -59,6 +59,9 @@ grpcBindAddr="localhost:8802"
whitelist=["127.0.0.1"] whitelist=["127.0.0.1"]
jrpcFuncWhitelist=["*"] jrpcFuncWhitelist=["*"]
grpcFuncWhitelist=["*"] grpcFuncWhitelist=["*"]
enableTLS=true
certFile="cert.pem"
keyFile="key.pem"
[mempool] [mempool]
poolCacheSize=10240 poolCacheSize=10240
......
...@@ -11,6 +11,7 @@ import ( ...@@ -11,6 +11,7 @@ import (
"testing" "testing"
"github.com/33cn/chain33/common/address" "github.com/33cn/chain33/common/address"
"github.com/33cn/chain33/common/merkle"
_ "github.com/33cn/chain33/system" _ "github.com/33cn/chain33/system"
"github.com/33cn/chain33/types" "github.com/33cn/chain33/types"
"github.com/33cn/chain33/util" "github.com/33cn/chain33/util"
...@@ -214,6 +215,34 @@ func TestExecBlock2(t *testing.T) { ...@@ -214,6 +215,34 @@ func TestExecBlock2(t *testing.T) {
} }
} }
var zeroHash [32]byte
func TestSameTx(t *testing.T) {
mock33 := newMockNode()
defer mock33.Close()
newblock := &types.Block{}
newblock.Height = 1
newblock.BlockTime = types.Now().Unix()
newblock.ParentHash = zeroHash[:]
newblock.Txs = util.GenNoneTxs(mock33.GetGenesisKey(), 3)
hash1 := merkle.CalcMerkleRoot(newblock.Txs)
newblock.Txs = append(newblock.Txs, newblock.Txs[2])
newblock.TxHash = merkle.CalcMerkleRoot(newblock.Txs)
assert.Equal(t, hash1, newblock.TxHash)
_, _, err := util.ExecBlock(mock33.GetClient(), nil, newblock, true, true)
assert.Equal(t, types.ErrTxDup, err)
//情况2
//[tx1,xt2,tx3,tx4,tx5,tx6] and [tx1,xt2,tx3,tx4,tx5,tx6,tx5,tx6]
newblock.Txs = util.GenNoneTxs(mock33.GetGenesisKey(), 6)
hash1 = merkle.CalcMerkleRoot(newblock.Txs)
newblock.Txs = append(newblock.Txs, newblock.Txs[4:]...)
newblock.TxHash = merkle.CalcMerkleRoot(newblock.Txs)
assert.Equal(t, hash1, newblock.TxHash)
_, _, err = util.ExecBlock(mock33.GetClient(), nil, newblock, true, true)
assert.Equal(t, types.ErrTxDup, err)
}
func TestExecBlock(t *testing.T) { func TestExecBlock(t *testing.T) {
mock33 := newMockNode() mock33 := newMockNode()
defer mock33.Close() defer mock33.Close()
......
...@@ -47,6 +47,11 @@ func (g *Grpc) CreateTransaction(ctx context.Context, in *pb.CreateTxIn) (*pb.Un ...@@ -47,6 +47,11 @@ func (g *Grpc) CreateTransaction(ctx context.Context, in *pb.CreateTxIn) (*pb.Un
if err != nil { if err != nil {
return nil, err return nil, err
} }
//decode protocol buffer
err = pb.Decode(in.Payload, msg)
if err != nil {
return nil, err
}
reply, err := pb.CallCreateTx(string(in.Execer), in.ActionName, msg) reply, err := pb.CallCreateTx(string(in.Execer), in.ActionName, msg)
if err != nil { if err != nil {
return nil, err return nil, err
......
...@@ -80,7 +80,10 @@ func (j *JSONRPCServer) Listen() (int, error) { ...@@ -80,7 +80,10 @@ func (j *JSONRPCServer) Listen() (int, error) {
if err != nil { if err != nil {
errstr = err.Error() errstr = err.Error()
} }
funcName := strings.Split(client.Method, ".")[len(strings.Split(client.Method, "."))-1]
if !checkFilterPrintFuncBlacklist(funcName) {
log.Debug("JSONRPCServer", "request", string(data), "err", errstr) log.Debug("JSONRPCServer", "request", string(data), "err", errstr)
}
if err != nil { if err != nil {
writeError(w, r, 0, fmt.Sprintf(`parse request err %s`, err.Error())) writeError(w, r, 0, fmt.Sprintf(`parse request err %s`, err.Error()))
return return
...@@ -88,7 +91,7 @@ func (j *JSONRPCServer) Listen() (int, error) { ...@@ -88,7 +91,7 @@ func (j *JSONRPCServer) Listen() (int, error) {
//Release local request //Release local request
ipaddr := net.ParseIP(ip) ipaddr := net.ParseIP(ip)
if !ipaddr.IsLoopback() { if !ipaddr.IsLoopback() {
funcName := strings.Split(client.Method, ".")[len(strings.Split(client.Method, "."))-1] //funcName := strings.Split(client.Method, ".")[len(strings.Split(client.Method, "."))-1]
if checkJrpcFuncBlacklist(funcName) || !checkJrpcFuncWhitelist(funcName) { if checkJrpcFuncBlacklist(funcName) || !checkJrpcFuncWhitelist(funcName) {
writeError(w, r, client.ID, fmt.Sprintf(`The %s method is not authorized!`, funcName)) writeError(w, r, client.ID, fmt.Sprintf(`The %s method is not authorized!`, funcName))
return return
...@@ -109,7 +112,11 @@ func (j *JSONRPCServer) Listen() (int, error) { ...@@ -109,7 +112,11 @@ func (j *JSONRPCServer) Listen() (int, error) {
}) })
handler = co.Handler(handler) handler = co.Handler(handler)
if !rpcCfg.EnableTLS {
go http.Serve(listener, handler) go http.Serve(listener, handler)
} else {
go http.ServeTLS(listener, handler, rpcCfg.CertFile, rpcCfg.KeyFile)
}
return listener.Addr().(*net.TCPAddr).Port, nil return listener.Addr().(*net.TCPAddr).Port, nil
} }
......
...@@ -165,43 +165,8 @@ func (c *Chain33) GetBlocks(in rpctypes.BlockParam, result *interface{}) error { ...@@ -165,43 +165,8 @@ func (c *Chain33) GetBlocks(in rpctypes.BlockParam, result *interface{}) error {
{ {
var blockDetails rpctypes.BlockDetails var blockDetails rpctypes.BlockDetails
items := reply.GetItems() items := reply.GetItems()
for _, item := range items { if err := convertBlockDetails(items, &blockDetails, in.Isdetail); err != nil {
var bdtl rpctypes.BlockDetail return err
var block rpctypes.Block
block.BlockTime = item.Block.GetBlockTime()
block.Height = item.Block.GetHeight()
block.Version = item.Block.GetVersion()
block.ParentHash = common.ToHex(item.Block.GetParentHash())
block.StateHash = common.ToHex(item.Block.GetStateHash())
block.TxHash = common.ToHex(item.Block.GetTxHash())
txs := item.Block.GetTxs()
if in.Isdetail && len(txs) != len(item.Receipts) { //只有获取详情时才需要校验txs和Receipts的数量是否相等CHAIN33-540
return types.ErrDecode
}
for _, tx := range txs {
tran, err := rpctypes.DecodeTx(tx)
if err != nil {
continue
}
block.Txs = append(block.Txs, tran)
}
bdtl.Block = &block
for i, rp := range item.Receipts {
var recp rpctypes.ReceiptData
recp.Ty = rp.GetTy()
for _, log := range rp.Logs {
recp.Logs = append(recp.Logs,
&rpctypes.ReceiptLog{Ty: log.Ty, Log: common.ToHex(log.GetLog())})
}
rd, err := rpctypes.DecodeLog(txs[i].Execer, &recp)
if err != nil {
continue
}
bdtl.Receipts = append(bdtl.Receipts, rd)
}
blockDetails.Items = append(blockDetails.Items, &bdtl)
} }
*result = &blockDetails *result = &blockDetails
} }
...@@ -1139,7 +1104,14 @@ func (c *Chain33) GetBlockByHashes(in rpctypes.ReqHashes, result *interface{}) e ...@@ -1139,7 +1104,14 @@ func (c *Chain33) GetBlockByHashes(in rpctypes.ReqHashes, result *interface{}) e
if err != nil { if err != nil {
return err return err
} }
*result = reply {
var blockDetails rpctypes.BlockDetails
items := reply.Items
if err := convertBlockDetails(items, &blockDetails, !in.DisableDetail); err != nil {
return err
}
*result = &blockDetails
}
return nil return nil
} }
...@@ -1148,16 +1120,11 @@ func (c *Chain33) CreateTransaction(in *rpctypes.CreateTxIn, result *interface{} ...@@ -1148,16 +1120,11 @@ func (c *Chain33) CreateTransaction(in *rpctypes.CreateTxIn, result *interface{}
if in == nil { if in == nil {
return types.ErrInvalidParam return types.ErrInvalidParam
} }
exec := types.LoadExecutorType(in.Execer) btx, err := types.CallCreateTxJSON(in.Execer, in.ActionName, in.Payload)
if exec == nil {
return types.ErrExecNameNotAllow
}
tx, err := exec.CreateTx(in.ActionName, in.Payload)
if err != nil { if err != nil {
log.Error("CreateTransaction", "err", err.Error())
return err return err
} }
*result = hex.EncodeToString(types.Encode(tx)) *result = hex.EncodeToString(btx)
return nil return nil
} }
...@@ -1177,3 +1144,80 @@ func (c *Chain33) GetExecBalance(in *types.ReqGetExecBalance, result *interface{ ...@@ -1177,3 +1144,80 @@ func (c *Chain33) GetExecBalance(in *types.ReqGetExecBalance, result *interface{
*result = hex.EncodeToString(types.Encode(resp)) *result = hex.EncodeToString(types.Encode(resp))
return nil return nil
} }
// AddSeqCallBack add Seq CallBack
func (c *Chain33) AddSeqCallBack(in *types.BlockSeqCB, result *interface{}) error {
reply, err := c.cli.AddSeqCallBack(in)
log.Error("AddSeqCallBack", "err", err, "reply", reply)
if err != nil {
return err
}
var resp rpctypes.Reply
resp.IsOk = reply.GetIsOk()
resp.Msg = string(reply.GetMsg())
*result = &resp
return nil
}
// ListSeqCallBack List Seq CallBack
func (c *Chain33) ListSeqCallBack(in *types.ReqNil, result *interface{}) error {
resp, err := c.cli.ListSeqCallBack()
if err != nil {
return err
}
*result = resp
return nil
}
// GetSeqCallBackLastNum Get Seq Call Back Last Num
func (c *Chain33) GetSeqCallBackLastNum(in *types.ReqString, result *interface{}) error {
resp, err := c.cli.GetSeqCallBackLastNum(in)
if err != nil {
return err
}
*result = resp
return nil
}
func convertBlockDetails(details []*types.BlockDetail, retDetails *rpctypes.BlockDetails, isDetail bool) error {
for _, item := range details {
var bdtl rpctypes.BlockDetail
var block rpctypes.Block
block.BlockTime = item.Block.GetBlockTime()
block.Height = item.Block.GetHeight()
block.Version = item.Block.GetVersion()
block.ParentHash = common.ToHex(item.Block.GetParentHash())
block.StateHash = common.ToHex(item.Block.GetStateHash())
block.TxHash = common.ToHex(item.Block.GetTxHash())
txs := item.Block.GetTxs()
if isDetail && len(txs) != len(item.Receipts) { //只有获取详情时才需要校验txs和Receipts的数量是否相等CHAIN33-540
return types.ErrDecode
}
for _, tx := range txs {
tran, err := rpctypes.DecodeTx(tx)
if err != nil {
continue
}
block.Txs = append(block.Txs, tran)
}
bdtl.Block = &block
for i, rp := range item.Receipts {
var recp rpctypes.ReceiptData
recp.Ty = rp.GetTy()
for _, log := range rp.Logs {
recp.Logs = append(recp.Logs,
&rpctypes.ReceiptLog{Ty: log.Ty, Log: common.ToHex(log.GetLog())})
}
rd, err := rpctypes.DecodeLog(txs[i].Execer, &recp)
if err != nil {
continue
}
bdtl.Receipts = append(bdtl.Receipts, rd)
}
retDetails.Items = append(retDetails.Items, &bdtl)
}
return nil
}
...@@ -1229,7 +1229,7 @@ func TestChain33_CreateTransaction(t *testing.T) { ...@@ -1229,7 +1229,7 @@ func TestChain33_CreateTransaction(t *testing.T) {
in := &rpctypes.CreateTxIn{Execer: "notExist", ActionName: "x", Payload: []byte("x")} in := &rpctypes.CreateTxIn{Execer: "notExist", ActionName: "x", Payload: []byte("x")}
err = client.CreateTransaction(in, &result) err = client.CreateTransaction(in, &result)
assert.Equal(t, types.ErrExecNameNotAllow, err) assert.Equal(t, types.ErrNotSupport, err)
in = &rpctypes.CreateTxIn{Execer: types.ExecName("coins"), ActionName: "notExist", Payload: []byte("x")} in = &rpctypes.CreateTxIn{Execer: types.ExecName("coins"), ActionName: "notExist", Payload: []byte("x")}
err = client.CreateTransaction(in, &result) err = client.CreateTransaction(in, &result)
......
...@@ -7,6 +7,7 @@ package jsonclient ...@@ -7,6 +7,7 @@ package jsonclient
import ( import (
"bytes" "bytes"
"crypto/tls"
"encoding/json" "encoding/json"
"fmt" "fmt"
"io/ioutil" "io/ioutil"
...@@ -21,6 +22,8 @@ import ( ...@@ -21,6 +22,8 @@ import (
type JSONClient struct { type JSONClient struct {
url string url string
prefix string prefix string
tlsVerify bool
client *http.Client
} }
func addPrefix(prefix, name string) string { func addPrefix(prefix, name string) string {
...@@ -32,12 +35,21 @@ func addPrefix(prefix, name string) string { ...@@ -32,12 +35,21 @@ func addPrefix(prefix, name string) string {
// NewJSONClient produce a json object // NewJSONClient produce a json object
func NewJSONClient(url string) (*JSONClient, error) { func NewJSONClient(url string) (*JSONClient, error) {
return &JSONClient{url: url, prefix: "Chain33"}, nil return New("Chain33", url, false)
} }
// New produce a jsonclient by perfix and url // New produce a jsonclient by perfix and url
func New(prefix, url string) (*JSONClient, error) { func New(prefix, url string, tlsVerify bool) (*JSONClient, error) {
return &JSONClient{url: url, prefix: prefix}, nil httpcli := http.DefaultClient
if strings.Contains(url, "https") { //暂不校验tls证书
httpcli = &http.Client{Transport: &http.Transport{TLSClientConfig: &tls.Config{InsecureSkipVerify: !tlsVerify}}}
}
return &JSONClient{
url: url,
prefix: prefix,
tlsVerify: tlsVerify,
client: httpcli,
}, nil
} }
type clientRequest struct { type clientRequest struct {
...@@ -63,7 +75,7 @@ func (client *JSONClient) Call(method string, params, resp interface{}) error { ...@@ -63,7 +75,7 @@ func (client *JSONClient) Call(method string, params, resp interface{}) error {
return err return err
} }
//println("request JsonStr", string(data), "") //println("request JsonStr", string(data), "")
postresp, err := http.Post(client.url, "application/json", bytes.NewBuffer(data)) postresp, err := client.client.Post(client.url, "application/json", bytes.NewBuffer(data))
if err != nil { if err != nil {
return err return err
} }
......
...@@ -14,8 +14,8 @@ import ( ...@@ -14,8 +14,8 @@ import (
"github.com/33cn/chain33/queue" "github.com/33cn/chain33/queue"
"github.com/33cn/chain33/types" "github.com/33cn/chain33/types"
"golang.org/x/net/context" "golang.org/x/net/context"
"google.golang.org/grpc" "google.golang.org/grpc"
"google.golang.org/grpc/credentials"
_ "google.golang.org/grpc/encoding/gzip" // register gzip _ "google.golang.org/grpc/encoding/gzip" // register gzip
) )
...@@ -26,6 +26,7 @@ var ( ...@@ -26,6 +26,7 @@ var (
grpcFuncWhitelist = make(map[string]bool) grpcFuncWhitelist = make(map[string]bool)
jrpcFuncBlacklist = make(map[string]bool) jrpcFuncBlacklist = make(map[string]bool)
grpcFuncBlacklist = make(map[string]bool) grpcFuncBlacklist = make(map[string]bool)
rpcFilterPrintFuncBlacklist = make(map[string]bool)
) )
// Chain33 a channel client // Chain33 a channel client
...@@ -149,6 +150,14 @@ func NewGRpcServer(c queue.Client, api client.QueueProtocolAPI) *Grpcserver { ...@@ -149,6 +150,14 @@ func NewGRpcServer(c queue.Client, api client.QueueProtocolAPI) *Grpcserver {
return handler(ctx, req) return handler(ctx, req)
} }
opts = append(opts, grpc.UnaryInterceptor(interceptor)) opts = append(opts, grpc.UnaryInterceptor(interceptor))
if rpcCfg.EnableTLS {
creds, err := credentials.NewServerTLSFromFile(rpcCfg.CertFile, rpcCfg.KeyFile)
if err != nil {
panic(err)
}
credsOps := grpc.Creds(creds)
opts = append(opts, credsOps)
}
server := grpc.NewServer(opts...) server := grpc.NewServer(opts...)
s.s = server s.s = server
types.RegisterChain33Server(server, s.grpc) types.RegisterChain33Server(server, s.grpc)
...@@ -182,6 +191,7 @@ func InitCfg(cfg *types.RPC) { ...@@ -182,6 +191,7 @@ func InitCfg(cfg *types.RPC) {
InitGrpcFuncWhitelist(cfg) InitGrpcFuncWhitelist(cfg)
InitJrpcFuncBlacklist(cfg) InitJrpcFuncBlacklist(cfg)
InitGrpcFuncBlacklist(cfg) InitGrpcFuncBlacklist(cfg)
InitFilterPrintFuncBlacklist()
} }
// New produce a rpc by cfg // New produce a rpc by cfg
...@@ -346,3 +356,19 @@ func InitGrpcFuncBlacklist(cfg *types.RPC) { ...@@ -346,3 +356,19 @@ func InitGrpcFuncBlacklist(cfg *types.RPC) {
grpcFuncBlacklist[funcName] = true grpcFuncBlacklist[funcName] = true
} }
} }
// InitFilterPrintFuncBlacklist rpc模块打印requet信息时需要过滤掉一些敏感接口的入参打印,比如钱包密码相关的
func InitFilterPrintFuncBlacklist() {
rpcFilterPrintFuncBlacklist["UnLock"] = true
rpcFilterPrintFuncBlacklist["SetPasswd"] = true
rpcFilterPrintFuncBlacklist["GetSeed"] = true
rpcFilterPrintFuncBlacklist["SaveSeed"] = true
rpcFilterPrintFuncBlacklist["ImportPrivkey"] = true
}
func checkFilterPrintFuncBlacklist(funcName string) bool {
if _, ok := rpcFilterPrintFuncBlacklist[funcName]; ok {
return true
}
return false
}
...@@ -122,6 +122,7 @@ func DecodeTx(tx *types.Transaction) (*Transaction, error) { ...@@ -122,6 +122,7 @@ func DecodeTx(tx *types.Transaction) (*Transaction, error) {
GroupCount: tx.GroupCount, GroupCount: tx.GroupCount,
Header: common.ToHex(tx.Header), Header: common.ToHex(tx.Header),
Next: common.ToHex(tx.Next), Next: common.ToHex(tx.Next),
Hash: common.ToHex(tx.Hash()),
} }
if result.Amount != 0 { if result.Amount != 0 {
result.AmountFmt = strconv.FormatFloat(float64(result.Amount)/float64(types.Coin), 'f', 4, 64) result.AmountFmt = strconv.FormatFloat(float64(result.Amount)/float64(types.Coin), 'f', 4, 64)
......
...@@ -83,6 +83,7 @@ type Transaction struct { ...@@ -83,6 +83,7 @@ type Transaction struct {
GroupCount int32 `json:"groupCount,omitempty"` GroupCount int32 `json:"groupCount,omitempty"`
Header string `json:"header,omitempty"` Header string `json:"header,omitempty"`
Next string `json:"next,omitempty"` Next string `json:"next,omitempty"`
Hash string `json:"hash,omitempty"`
} }
// ReceiptLog defines receipt log command // ReceiptLog defines receipt log command
......
...@@ -47,6 +47,12 @@ func New(cfg *types.Consensus, sub []byte) queue.Module { ...@@ -47,6 +47,12 @@ func New(cfg *types.Consensus, sub []byte) queue.Module {
if subcfg.WaitTxMs == 0 { if subcfg.WaitTxMs == 0 {
subcfg.WaitTxMs = 1000 subcfg.WaitTxMs = 1000
} }
if subcfg.Genesis == "" {
subcfg.Genesis = cfg.Genesis
}
if subcfg.GenesisBlockTime == 0 {
subcfg.GenesisBlockTime = cfg.GenesisBlockTime
}
solo := &Client{c, &subcfg, time.Duration(subcfg.WaitTxMs) * time.Millisecond} solo := &Client{c, &subcfg, time.Duration(subcfg.WaitTxMs) * time.Millisecond}
c.SetChild(solo) c.SetChild(solo)
return solo return solo
......
...@@ -35,6 +35,9 @@ func BlockCmd() *cobra.Command { ...@@ -35,6 +35,9 @@ func BlockCmd() *cobra.Command {
GetBlockByHashsCmd(), GetBlockByHashsCmd(),
GetBlockSequencesCmd(), GetBlockSequencesCmd(),
GetLastBlockSequenceCmd(), GetLastBlockSequenceCmd(),
AddBlockSeqCallBackCmd(),
ListBlockSeqCallBackCmd(),
GetSeqCallBackLastNumCmd(),
) )
return cmd return cmd
...@@ -295,3 +298,89 @@ func getblockbyhashs(cmd *cobra.Command, args []string) { ...@@ -295,3 +298,89 @@ func getblockbyhashs(cmd *cobra.Command, args []string) {
//ctx.SetResultCb(parseQueryTxsByHashesRes) //ctx.SetResultCb(parseQueryTxsByHashesRes)
ctx.Run() ctx.Run()
} }
// AddBlockSeqCallBackCmd add block sequence call back
func AddBlockSeqCallBackCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "add_callback",
Short: "add block sequence call back",
Run: addblockSeqCallBackCmd,
}
addblockSeqCallBackCmdFlags(cmd)
return cmd
}
func addblockSeqCallBackCmdFlags(cmd *cobra.Command) {
cmd.Flags().StringP("name", "n", "", "call back name")
cmd.MarkFlagRequired("name")
cmd.Flags().StringP("url", "u", "", "call back URL")
cmd.MarkFlagRequired("url")
cmd.Flags().StringP("encode", "e", "", "data encode type,json or proto buff")
cmd.MarkFlagRequired("encode")
}
func addblockSeqCallBackCmd(cmd *cobra.Command, args []string) {
rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
name, _ := cmd.Flags().GetString("name")
url, _ := cmd.Flags().GetString("url")
encode, _ := cmd.Flags().GetString("encode")
params := types.BlockSeqCB{
Name: name,
URL: url,
Encode: encode,
}
var res rpctypes.Reply
ctx := jsonclient.NewRPCCtx(rpcLaddr, "Chain33.AddSeqCallBack", params, &res)
ctx.Run()
}
// ListBlockSeqCallBackCmd list block sequence call back
func ListBlockSeqCallBackCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "list_callback",
Short: "list block sequence call back",
Run: listBlockSeqCallBackCmd,
}
return cmd
}
func listBlockSeqCallBackCmd(cmd *cobra.Command, args []string) {
rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
var res types.BlockSeqCBs
ctx := jsonclient.NewRPCCtx(rpcLaddr, "Chain33.ListSeqCallBack", nil, &res)
ctx.Run()
}
// GetSeqCallBackLastNumCmd Get Seq Call Back Last Num
func GetSeqCallBackLastNumCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "last_callback_sequence",
Short: "last call back sequence by name",
Run: getSeqCallBackLastNumCmd,
}
getSeqCallBackLastNumCmdFlags(cmd)
return cmd
}
func getSeqCallBackLastNumCmdFlags(cmd *cobra.Command) {
cmd.Flags().StringP("name", "n", "", "call back name")
cmd.MarkFlagRequired("name")
}
func getSeqCallBackLastNumCmd(cmd *cobra.Command, args []string) {
rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
name, _ := cmd.Flags().GetString("name")
params := types.ReqString{
Data: name,
}
var res types.Int64
ctx := jsonclient.NewRPCCtx(rpcLaddr, "Chain33.GetSeqCallBackLastNum", params, &res)
ctx.Run()
}
package commands
import (
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"crypto/x509/pkix"
"encoding/pem"
"fmt"
"math/big"
"net"
"os"
"strings"
"time"
"github.com/spf13/cobra"
)
//CertCmd generate cert
func CertCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "cert",
Short: "generate cert",
Run: func(cmd *cobra.Command, args []string) {
host, _ := cmd.Flags().GetString("host")
validFrom, _ := cmd.Flags().GetString("start-date")
ecdsaCurve, _ := cmd.Flags().GetString("ecdsa-curve")
rsaBits, _ := cmd.Flags().GetInt("rsa-bits")
isCA, _ := cmd.Flags().GetBool("ca")
validFor, _ := cmd.Flags().GetDuration("duration")
certGenerate(host, validFrom, ecdsaCurve, rsaBits, isCA, validFor)
},
}
addCertFlags(cmd)
return cmd
}
func addCertFlags(cmd *cobra.Command) {
cmd.Flags().StringP("host", "", "", "Comma-separated hostnames and IPs to generate a certificate for")
cmd.Flags().StringP("start-date", "", "", "Creation date formatted as Jan 1 15:04:05 2011")
cmd.Flags().StringP("ecdsa-curve", "", "", "ECDSA curve to use to generate a key. Valid values are P224, P256 (recommended), P384, P521")
cmd.Flags().IntP("rsa-bits", "", 2048, "Size of RSA key to generate. Ignored if --ecdsa-curve is set")
cmd.Flags().Bool("ca", false, "whether this cert should be its own Certificate Authority")
cmd.Flags().Duration("duration", 365*24*time.Hour, "Duration that certificate is valid for")
cmd.MarkFlagRequired("host")
}
func publicKey(priv interface{}) interface{} {
switch k := priv.(type) {
case *rsa.PrivateKey:
return &k.PublicKey
case *ecdsa.PrivateKey:
return &k.PublicKey
default:
return nil
}
}
func pemBlockForKey(priv interface{}) *pem.Block {
switch k := priv.(type) {
case *rsa.PrivateKey:
return &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(k)}
case *ecdsa.PrivateKey:
b, err := x509.MarshalECPrivateKey(k)
if err != nil {
fmt.Fprintf(os.Stderr, "Unable to marshal ECDSA private key: %v", err)
os.Exit(2)
}
return &pem.Block{Type: "EC PRIVATE KEY", Bytes: b}
default:
return nil
}
}
func certGenerate(host, validFrom, ecdsaCurve string, rsaBits int, isCA bool, validFor time.Duration) {
var priv interface{}
var err error
switch ecdsaCurve {
case "":
priv, err = rsa.GenerateKey(rand.Reader, rsaBits)
case "P224":
priv, err = ecdsa.GenerateKey(elliptic.P224(), rand.Reader)
case "P256":
priv, err = ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
case "P384":
priv, err = ecdsa.GenerateKey(elliptic.P384(), rand.Reader)
case "P521":
priv, err = ecdsa.GenerateKey(elliptic.P521(), rand.Reader)
default:
fmt.Fprintf(os.Stderr, "Unrecognized elliptic curve: %q", ecdsaCurve)
os.Exit(1)
}
if err != nil {
fmt.Fprintf(os.Stderr, "failed to generate private key: %s\n", err)
os.Exit(1)
}
var notBefore time.Time
if len(validFrom) == 0 {
notBefore = time.Now()
} else {
notBefore, err = time.Parse("Jan 2 15:04:05 2006", validFrom)
if err != nil {
fmt.Fprintf(os.Stderr, "Failed to parse creation date: %s\n", err)
os.Exit(1)
}
}
notAfter := notBefore.Add(validFor)
serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128)
serialNumber, err := rand.Int(rand.Reader, serialNumberLimit)
if err != nil {
fmt.Fprintf(os.Stderr, "failed to generate serial number: %s", err)
os.Exit(1)
}
template := x509.Certificate{
SerialNumber: serialNumber,
Subject: pkix.Name{
Organization: []string{"Acme Co"},
},
NotBefore: notBefore,
NotAfter: notAfter,
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
BasicConstraintsValid: true,
}
hosts := strings.Split(host, ",")
for _, h := range hosts {
if ip := net.ParseIP(h); ip != nil {
template.IPAddresses = append(template.IPAddresses, ip)
} else {
template.DNSNames = append(template.DNSNames, h)
}
}
if isCA {
template.IsCA = true
template.KeyUsage |= x509.KeyUsageCertSign
}
derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, publicKey(priv), priv)
if err != nil {
fmt.Fprintf(os.Stderr, "Failed to create certificate: %s", err)
os.Exit(1)
}
certOut, err := os.Create("cert.pem")
if err != nil {
fmt.Fprintf(os.Stderr, "failed to open cert.pem for writing: %s", err)
os.Exit(1)
}
if err := pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes}); err != nil {
fmt.Fprintf(os.Stderr, "failed to write data to cert.pem: %s", err)
os.Exit(1)
}
if err := certOut.Close(); err != nil {
fmt.Fprintf(os.Stderr, "error closing cert.pem: %s", err)
os.Exit(1)
}
fmt.Print("wrote cert.pem\n")
keyOut, err := os.OpenFile("key.pem", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
if err != nil {
fmt.Fprintf(os.Stderr, "failed to open key.pem for writing: %s", err)
os.Exit(1)
}
if err := pem.Encode(keyOut, pemBlockForKey(priv)); err != nil {
fmt.Fprintf(os.Stderr, "failed to write data to key.pem: %s", err)
os.Exit(1)
}
if err := keyOut.Close(); err != nil {
fmt.Fprintf(os.Stderr, "error closing key.pem: %s", err)
os.Exit(1)
}
fmt.Print("wrote key.pem\n")
}
...@@ -58,6 +58,7 @@ type TxResult struct { ...@@ -58,6 +58,7 @@ type TxResult struct {
GroupCount int32 `json:"groupCount,omitempty"` GroupCount int32 `json:"groupCount,omitempty"`
Header string `json:"header,omitempty"` Header string `json:"header,omitempty"`
Next string `json:"next,omitempty"` Next string `json:"next,omitempty"`
Hash string `json:"hash,omitempty"`
} }
// ReceiptAccountTransfer defines receipt account transfer // ReceiptAccountTransfer defines receipt account transfer
......
...@@ -39,6 +39,7 @@ func DecodeTransaction(tx *rpctypes.Transaction) *TxResult { ...@@ -39,6 +39,7 @@ func DecodeTransaction(tx *rpctypes.Transaction) *TxResult {
GroupCount: tx.GroupCount, GroupCount: tx.GroupCount,
Header: tx.Header, Header: tx.Header,
Next: tx.Next, Next: tx.Next,
Hash: tx.Hash,
} }
return result return result
} }
......
...@@ -353,7 +353,7 @@ func parseTxHeight(expire string) error { ...@@ -353,7 +353,7 @@ func parseTxHeight(expire string) error {
return err return err
} }
if txHeight <= 0 { if txHeight <= 0 {
fmt.Printf("txHeight should be grate to 0") //fmt.Printf("txHeight should be grate to 0")
return errors.New("txHeight should be grate to 0") return errors.New("txHeight should be grate to 0")
} }
......
...@@ -6,7 +6,6 @@ ...@@ -6,7 +6,6 @@
package types package types
import ( import (
"encoding/json"
"reflect" "reflect"
"github.com/33cn/chain33/common/address" "github.com/33cn/chain33/common/address"
...@@ -60,13 +59,6 @@ func (m ManageType) Amount(tx *types.Transaction) (int64, error) { ...@@ -60,13 +59,6 @@ func (m ManageType) Amount(tx *types.Transaction) (int64, error) {
return 0, nil return 0, nil
} }
// CreateTx create a tx
// TODO not going to change the implementation, complete the reconfiguration of the structure first
func (m ManageType) CreateTx(action string, message json.RawMessage) (*types.Transaction, error) {
var tx *types.Transaction
return tx, nil
}
// GetLogMap get log for map // GetLogMap get log for map
func (m *ManageType) GetLogMap() map[int64]*types.LogInfo { func (m *ManageType) GetLogMap() map[int64]*types.LogInfo {
return logmap return logmap
...@@ -86,3 +78,8 @@ func (m ManageType) GetRealToAddr(tx *types.Transaction) string { ...@@ -86,3 +78,8 @@ func (m ManageType) GetRealToAddr(tx *types.Transaction) string {
func (m ManageType) GetTypeMap() map[string]int32 { func (m ManageType) GetTypeMap() map[string]int32 {
return actionName return actionName
} }
// GetName reset name
func (m *ManageType) GetName() string {
return ManageX
}
...@@ -340,6 +340,45 @@ func (m *BlockSeqCB) GetEncode() string { ...@@ -340,6 +340,45 @@ func (m *BlockSeqCB) GetEncode() string {
return "" return ""
} }
type BlockSeqCBs struct {
Items []*BlockSeqCB `protobuf:"bytes,1,rep,name=items,proto3" json:"items,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *BlockSeqCBs) Reset() { *m = BlockSeqCBs{} }
func (m *BlockSeqCBs) String() string { return proto.CompactTextString(m) }
func (*BlockSeqCBs) ProtoMessage() {}
func (*BlockSeqCBs) Descriptor() ([]byte, []int) {
return fileDescriptor_e9ac6287ce250c9a, []int{4}
}
func (m *BlockSeqCBs) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_BlockSeqCBs.Unmarshal(m, b)
}
func (m *BlockSeqCBs) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_BlockSeqCBs.Marshal(b, m, deterministic)
}
func (m *BlockSeqCBs) XXX_Merge(src proto.Message) {
xxx_messageInfo_BlockSeqCBs.Merge(m, src)
}
func (m *BlockSeqCBs) XXX_Size() int {
return xxx_messageInfo_BlockSeqCBs.Size(m)
}
func (m *BlockSeqCBs) XXX_DiscardUnknown() {
xxx_messageInfo_BlockSeqCBs.DiscardUnknown(m)
}
var xxx_messageInfo_BlockSeqCBs proto.InternalMessageInfo
func (m *BlockSeqCBs) GetItems() []*BlockSeqCB {
if m != nil {
return m.Items
}
return nil
}
type BlockSeq struct { type BlockSeq struct {
Num int64 `protobuf:"varint,1,opt,name=num,proto3" json:"num,omitempty"` Num int64 `protobuf:"varint,1,opt,name=num,proto3" json:"num,omitempty"`
Seq *BlockSequence `protobuf:"bytes,2,opt,name=seq,proto3" json:"seq,omitempty"` Seq *BlockSequence `protobuf:"bytes,2,opt,name=seq,proto3" json:"seq,omitempty"`
...@@ -353,7 +392,7 @@ func (m *BlockSeq) Reset() { *m = BlockSeq{} } ...@@ -353,7 +392,7 @@ func (m *BlockSeq) Reset() { *m = BlockSeq{} }
func (m *BlockSeq) String() string { return proto.CompactTextString(m) } func (m *BlockSeq) String() string { return proto.CompactTextString(m) }
func (*BlockSeq) ProtoMessage() {} func (*BlockSeq) ProtoMessage() {}
func (*BlockSeq) Descriptor() ([]byte, []int) { func (*BlockSeq) Descriptor() ([]byte, []int) {
return fileDescriptor_e9ac6287ce250c9a, []int{4} return fileDescriptor_e9ac6287ce250c9a, []int{5}
} }
func (m *BlockSeq) XXX_Unmarshal(b []byte) error { func (m *BlockSeq) XXX_Unmarshal(b []byte) error {
...@@ -408,7 +447,7 @@ func (m *BlockPid) Reset() { *m = BlockPid{} } ...@@ -408,7 +447,7 @@ func (m *BlockPid) Reset() { *m = BlockPid{} }
func (m *BlockPid) String() string { return proto.CompactTextString(m) } func (m *BlockPid) String() string { return proto.CompactTextString(m) }
func (*BlockPid) ProtoMessage() {} func (*BlockPid) ProtoMessage() {}
func (*BlockPid) Descriptor() ([]byte, []int) { func (*BlockPid) Descriptor() ([]byte, []int) {
return fileDescriptor_e9ac6287ce250c9a, []int{5} return fileDescriptor_e9ac6287ce250c9a, []int{6}
} }
func (m *BlockPid) XXX_Unmarshal(b []byte) error { func (m *BlockPid) XXX_Unmarshal(b []byte) error {
...@@ -455,7 +494,7 @@ func (m *BlockDetails) Reset() { *m = BlockDetails{} } ...@@ -455,7 +494,7 @@ func (m *BlockDetails) Reset() { *m = BlockDetails{} }
func (m *BlockDetails) String() string { return proto.CompactTextString(m) } func (m *BlockDetails) String() string { return proto.CompactTextString(m) }
func (*BlockDetails) ProtoMessage() {} func (*BlockDetails) ProtoMessage() {}
func (*BlockDetails) Descriptor() ([]byte, []int) { func (*BlockDetails) Descriptor() ([]byte, []int) {
return fileDescriptor_e9ac6287ce250c9a, []int{6} return fileDescriptor_e9ac6287ce250c9a, []int{7}
} }
func (m *BlockDetails) XXX_Unmarshal(b []byte) error { func (m *BlockDetails) XXX_Unmarshal(b []byte) error {
...@@ -495,7 +534,7 @@ func (m *Headers) Reset() { *m = Headers{} } ...@@ -495,7 +534,7 @@ func (m *Headers) Reset() { *m = Headers{} }
func (m *Headers) String() string { return proto.CompactTextString(m) } func (m *Headers) String() string { return proto.CompactTextString(m) }
func (*Headers) ProtoMessage() {} func (*Headers) ProtoMessage() {}
func (*Headers) Descriptor() ([]byte, []int) { func (*Headers) Descriptor() ([]byte, []int) {
return fileDescriptor_e9ac6287ce250c9a, []int{7} return fileDescriptor_e9ac6287ce250c9a, []int{8}
} }
func (m *Headers) XXX_Unmarshal(b []byte) error { func (m *Headers) XXX_Unmarshal(b []byte) error {
...@@ -535,7 +574,7 @@ func (m *HeadersPid) Reset() { *m = HeadersPid{} } ...@@ -535,7 +574,7 @@ func (m *HeadersPid) Reset() { *m = HeadersPid{} }
func (m *HeadersPid) String() string { return proto.CompactTextString(m) } func (m *HeadersPid) String() string { return proto.CompactTextString(m) }
func (*HeadersPid) ProtoMessage() {} func (*HeadersPid) ProtoMessage() {}
func (*HeadersPid) Descriptor() ([]byte, []int) { func (*HeadersPid) Descriptor() ([]byte, []int) {
return fileDescriptor_e9ac6287ce250c9a, []int{8} return fileDescriptor_e9ac6287ce250c9a, []int{9}
} }
func (m *HeadersPid) XXX_Unmarshal(b []byte) error { func (m *HeadersPid) XXX_Unmarshal(b []byte) error {
...@@ -587,7 +626,7 @@ func (m *BlockOverview) Reset() { *m = BlockOverview{} } ...@@ -587,7 +626,7 @@ func (m *BlockOverview) Reset() { *m = BlockOverview{} }
func (m *BlockOverview) String() string { return proto.CompactTextString(m) } func (m *BlockOverview) String() string { return proto.CompactTextString(m) }
func (*BlockOverview) ProtoMessage() {} func (*BlockOverview) ProtoMessage() {}
func (*BlockOverview) Descriptor() ([]byte, []int) { func (*BlockOverview) Descriptor() ([]byte, []int) {
return fileDescriptor_e9ac6287ce250c9a, []int{9} return fileDescriptor_e9ac6287ce250c9a, []int{10}
} }
func (m *BlockOverview) XXX_Unmarshal(b []byte) error { func (m *BlockOverview) XXX_Unmarshal(b []byte) error {
...@@ -646,7 +685,7 @@ func (m *BlockDetail) Reset() { *m = BlockDetail{} } ...@@ -646,7 +685,7 @@ func (m *BlockDetail) Reset() { *m = BlockDetail{} }
func (m *BlockDetail) String() string { return proto.CompactTextString(m) } func (m *BlockDetail) String() string { return proto.CompactTextString(m) }
func (*BlockDetail) ProtoMessage() {} func (*BlockDetail) ProtoMessage() {}
func (*BlockDetail) Descriptor() ([]byte, []int) { func (*BlockDetail) Descriptor() ([]byte, []int) {
return fileDescriptor_e9ac6287ce250c9a, []int{10} return fileDescriptor_e9ac6287ce250c9a, []int{11}
} }
func (m *BlockDetail) XXX_Unmarshal(b []byte) error { func (m *BlockDetail) XXX_Unmarshal(b []byte) error {
...@@ -706,7 +745,7 @@ func (m *Receipts) Reset() { *m = Receipts{} } ...@@ -706,7 +745,7 @@ func (m *Receipts) Reset() { *m = Receipts{} }
func (m *Receipts) String() string { return proto.CompactTextString(m) } func (m *Receipts) String() string { return proto.CompactTextString(m) }
func (*Receipts) ProtoMessage() {} func (*Receipts) ProtoMessage() {}
func (*Receipts) Descriptor() ([]byte, []int) { func (*Receipts) Descriptor() ([]byte, []int) {
return fileDescriptor_e9ac6287ce250c9a, []int{11} return fileDescriptor_e9ac6287ce250c9a, []int{12}
} }
func (m *Receipts) XXX_Unmarshal(b []byte) error { func (m *Receipts) XXX_Unmarshal(b []byte) error {
...@@ -745,7 +784,7 @@ func (m *PrivacyKV) Reset() { *m = PrivacyKV{} } ...@@ -745,7 +784,7 @@ func (m *PrivacyKV) Reset() { *m = PrivacyKV{} }
func (m *PrivacyKV) String() string { return proto.CompactTextString(m) } func (m *PrivacyKV) String() string { return proto.CompactTextString(m) }
func (*PrivacyKV) ProtoMessage() {} func (*PrivacyKV) ProtoMessage() {}
func (*PrivacyKV) Descriptor() ([]byte, []int) { func (*PrivacyKV) Descriptor() ([]byte, []int) {
return fileDescriptor_e9ac6287ce250c9a, []int{12} return fileDescriptor_e9ac6287ce250c9a, []int{13}
} }
func (m *PrivacyKV) XXX_Unmarshal(b []byte) error { func (m *PrivacyKV) XXX_Unmarshal(b []byte) error {
...@@ -787,7 +826,7 @@ func (m *PrivacyKVToken) Reset() { *m = PrivacyKVToken{} } ...@@ -787,7 +826,7 @@ func (m *PrivacyKVToken) Reset() { *m = PrivacyKVToken{} }
func (m *PrivacyKVToken) String() string { return proto.CompactTextString(m) } func (m *PrivacyKVToken) String() string { return proto.CompactTextString(m) }
func (*PrivacyKVToken) ProtoMessage() {} func (*PrivacyKVToken) ProtoMessage() {}
func (*PrivacyKVToken) Descriptor() ([]byte, []int) { func (*PrivacyKVToken) Descriptor() ([]byte, []int) {
return fileDescriptor_e9ac6287ce250c9a, []int{13} return fileDescriptor_e9ac6287ce250c9a, []int{14}
} }
func (m *PrivacyKVToken) XXX_Unmarshal(b []byte) error { func (m *PrivacyKVToken) XXX_Unmarshal(b []byte) error {
...@@ -848,7 +887,7 @@ func (m *ReceiptsAndPrivacyKV) Reset() { *m = ReceiptsAndPrivacyKV{} } ...@@ -848,7 +887,7 @@ func (m *ReceiptsAndPrivacyKV) Reset() { *m = ReceiptsAndPrivacyKV{} }
func (m *ReceiptsAndPrivacyKV) String() string { return proto.CompactTextString(m) } func (m *ReceiptsAndPrivacyKV) String() string { return proto.CompactTextString(m) }
func (*ReceiptsAndPrivacyKV) ProtoMessage() {} func (*ReceiptsAndPrivacyKV) ProtoMessage() {}
func (*ReceiptsAndPrivacyKV) Descriptor() ([]byte, []int) { func (*ReceiptsAndPrivacyKV) Descriptor() ([]byte, []int) {
return fileDescriptor_e9ac6287ce250c9a, []int{14} return fileDescriptor_e9ac6287ce250c9a, []int{15}
} }
func (m *ReceiptsAndPrivacyKV) XXX_Unmarshal(b []byte) error { func (m *ReceiptsAndPrivacyKV) XXX_Unmarshal(b []byte) error {
...@@ -894,7 +933,7 @@ func (m *ReceiptCheckTxList) Reset() { *m = ReceiptCheckTxList{} } ...@@ -894,7 +933,7 @@ func (m *ReceiptCheckTxList) Reset() { *m = ReceiptCheckTxList{} }
func (m *ReceiptCheckTxList) String() string { return proto.CompactTextString(m) } func (m *ReceiptCheckTxList) String() string { return proto.CompactTextString(m) }
func (*ReceiptCheckTxList) ProtoMessage() {} func (*ReceiptCheckTxList) ProtoMessage() {}
func (*ReceiptCheckTxList) Descriptor() ([]byte, []int) { func (*ReceiptCheckTxList) Descriptor() ([]byte, []int) {
return fileDescriptor_e9ac6287ce250c9a, []int{15} return fileDescriptor_e9ac6287ce250c9a, []int{16}
} }
func (m *ReceiptCheckTxList) XXX_Unmarshal(b []byte) error { func (m *ReceiptCheckTxList) XXX_Unmarshal(b []byte) error {
...@@ -939,7 +978,7 @@ func (m *ChainStatus) Reset() { *m = ChainStatus{} } ...@@ -939,7 +978,7 @@ func (m *ChainStatus) Reset() { *m = ChainStatus{} }
func (m *ChainStatus) String() string { return proto.CompactTextString(m) } func (m *ChainStatus) String() string { return proto.CompactTextString(m) }
func (*ChainStatus) ProtoMessage() {} func (*ChainStatus) ProtoMessage() {}
func (*ChainStatus) Descriptor() ([]byte, []int) { func (*ChainStatus) Descriptor() ([]byte, []int) {
return fileDescriptor_e9ac6287ce250c9a, []int{16} return fileDescriptor_e9ac6287ce250c9a, []int{17}
} }
func (m *ChainStatus) XXX_Unmarshal(b []byte) error { func (m *ChainStatus) XXX_Unmarshal(b []byte) error {
...@@ -1000,7 +1039,7 @@ func (m *ReqBlocks) Reset() { *m = ReqBlocks{} } ...@@ -1000,7 +1039,7 @@ func (m *ReqBlocks) Reset() { *m = ReqBlocks{} }
func (m *ReqBlocks) String() string { return proto.CompactTextString(m) } func (m *ReqBlocks) String() string { return proto.CompactTextString(m) }
func (*ReqBlocks) ProtoMessage() {} func (*ReqBlocks) ProtoMessage() {}
func (*ReqBlocks) Descriptor() ([]byte, []int) { func (*ReqBlocks) Descriptor() ([]byte, []int) {
return fileDescriptor_e9ac6287ce250c9a, []int{17} return fileDescriptor_e9ac6287ce250c9a, []int{18}
} }
func (m *ReqBlocks) XXX_Unmarshal(b []byte) error { func (m *ReqBlocks) XXX_Unmarshal(b []byte) error {
...@@ -1060,7 +1099,7 @@ func (m *MempoolSize) Reset() { *m = MempoolSize{} } ...@@ -1060,7 +1099,7 @@ func (m *MempoolSize) Reset() { *m = MempoolSize{} }
func (m *MempoolSize) String() string { return proto.CompactTextString(m) } func (m *MempoolSize) String() string { return proto.CompactTextString(m) }
func (*MempoolSize) ProtoMessage() {} func (*MempoolSize) ProtoMessage() {}
func (*MempoolSize) Descriptor() ([]byte, []int) { func (*MempoolSize) Descriptor() ([]byte, []int) {
return fileDescriptor_e9ac6287ce250c9a, []int{18} return fileDescriptor_e9ac6287ce250c9a, []int{19}
} }
func (m *MempoolSize) XXX_Unmarshal(b []byte) error { func (m *MempoolSize) XXX_Unmarshal(b []byte) error {
...@@ -1099,7 +1138,7 @@ func (m *ReplyBlockHeight) Reset() { *m = ReplyBlockHeight{} } ...@@ -1099,7 +1138,7 @@ func (m *ReplyBlockHeight) Reset() { *m = ReplyBlockHeight{} }
func (m *ReplyBlockHeight) String() string { return proto.CompactTextString(m) } func (m *ReplyBlockHeight) String() string { return proto.CompactTextString(m) }
func (*ReplyBlockHeight) ProtoMessage() {} func (*ReplyBlockHeight) ProtoMessage() {}
func (*ReplyBlockHeight) Descriptor() ([]byte, []int) { func (*ReplyBlockHeight) Descriptor() ([]byte, []int) {
return fileDescriptor_e9ac6287ce250c9a, []int{19} return fileDescriptor_e9ac6287ce250c9a, []int{20}
} }
func (m *ReplyBlockHeight) XXX_Unmarshal(b []byte) error { func (m *ReplyBlockHeight) XXX_Unmarshal(b []byte) error {
...@@ -1142,7 +1181,7 @@ func (m *BlockBody) Reset() { *m = BlockBody{} } ...@@ -1142,7 +1181,7 @@ func (m *BlockBody) Reset() { *m = BlockBody{} }
func (m *BlockBody) String() string { return proto.CompactTextString(m) } func (m *BlockBody) String() string { return proto.CompactTextString(m) }
func (*BlockBody) ProtoMessage() {} func (*BlockBody) ProtoMessage() {}
func (*BlockBody) Descriptor() ([]byte, []int) { func (*BlockBody) Descriptor() ([]byte, []int) {
return fileDescriptor_e9ac6287ce250c9a, []int{20} return fileDescriptor_e9ac6287ce250c9a, []int{21}
} }
func (m *BlockBody) XXX_Unmarshal(b []byte) error { func (m *BlockBody) XXX_Unmarshal(b []byte) error {
...@@ -1189,7 +1228,7 @@ func (m *IsCaughtUp) Reset() { *m = IsCaughtUp{} } ...@@ -1189,7 +1228,7 @@ func (m *IsCaughtUp) Reset() { *m = IsCaughtUp{} }
func (m *IsCaughtUp) String() string { return proto.CompactTextString(m) } func (m *IsCaughtUp) String() string { return proto.CompactTextString(m) }
func (*IsCaughtUp) ProtoMessage() {} func (*IsCaughtUp) ProtoMessage() {}
func (*IsCaughtUp) Descriptor() ([]byte, []int) { func (*IsCaughtUp) Descriptor() ([]byte, []int) {
return fileDescriptor_e9ac6287ce250c9a, []int{21} return fileDescriptor_e9ac6287ce250c9a, []int{22}
} }
func (m *IsCaughtUp) XXX_Unmarshal(b []byte) error { func (m *IsCaughtUp) XXX_Unmarshal(b []byte) error {
...@@ -1229,7 +1268,7 @@ func (m *IsNtpClockSync) Reset() { *m = IsNtpClockSync{} } ...@@ -1229,7 +1268,7 @@ func (m *IsNtpClockSync) Reset() { *m = IsNtpClockSync{} }
func (m *IsNtpClockSync) String() string { return proto.CompactTextString(m) } func (m *IsNtpClockSync) String() string { return proto.CompactTextString(m) }
func (*IsNtpClockSync) ProtoMessage() {} func (*IsNtpClockSync) ProtoMessage() {}
func (*IsNtpClockSync) Descriptor() ([]byte, []int) { func (*IsNtpClockSync) Descriptor() ([]byte, []int) {
return fileDescriptor_e9ac6287ce250c9a, []int{22} return fileDescriptor_e9ac6287ce250c9a, []int{23}
} }
func (m *IsNtpClockSync) XXX_Unmarshal(b []byte) error { func (m *IsNtpClockSync) XXX_Unmarshal(b []byte) error {
...@@ -1273,7 +1312,7 @@ func (m *ChainExecutor) Reset() { *m = ChainExecutor{} } ...@@ -1273,7 +1312,7 @@ func (m *ChainExecutor) Reset() { *m = ChainExecutor{} }
func (m *ChainExecutor) String() string { return proto.CompactTextString(m) } func (m *ChainExecutor) String() string { return proto.CompactTextString(m) }
func (*ChainExecutor) ProtoMessage() {} func (*ChainExecutor) ProtoMessage() {}
func (*ChainExecutor) Descriptor() ([]byte, []int) { func (*ChainExecutor) Descriptor() ([]byte, []int) {
return fileDescriptor_e9ac6287ce250c9a, []int{23} return fileDescriptor_e9ac6287ce250c9a, []int{24}
} }
func (m *ChainExecutor) XXX_Unmarshal(b []byte) error { func (m *ChainExecutor) XXX_Unmarshal(b []byte) error {
...@@ -1342,7 +1381,7 @@ func (m *BlockSequence) Reset() { *m = BlockSequence{} } ...@@ -1342,7 +1381,7 @@ func (m *BlockSequence) Reset() { *m = BlockSequence{} }
func (m *BlockSequence) String() string { return proto.CompactTextString(m) } func (m *BlockSequence) String() string { return proto.CompactTextString(m) }
func (*BlockSequence) ProtoMessage() {} func (*BlockSequence) ProtoMessage() {}
func (*BlockSequence) Descriptor() ([]byte, []int) { func (*BlockSequence) Descriptor() ([]byte, []int) {
return fileDescriptor_e9ac6287ce250c9a, []int{24} return fileDescriptor_e9ac6287ce250c9a, []int{25}
} }
func (m *BlockSequence) XXX_Unmarshal(b []byte) error { func (m *BlockSequence) XXX_Unmarshal(b []byte) error {
...@@ -1389,7 +1428,7 @@ func (m *BlockSequences) Reset() { *m = BlockSequences{} } ...@@ -1389,7 +1428,7 @@ func (m *BlockSequences) Reset() { *m = BlockSequences{} }
func (m *BlockSequences) String() string { return proto.CompactTextString(m) } func (m *BlockSequences) String() string { return proto.CompactTextString(m) }
func (*BlockSequences) ProtoMessage() {} func (*BlockSequences) ProtoMessage() {}
func (*BlockSequences) Descriptor() ([]byte, []int) { func (*BlockSequences) Descriptor() ([]byte, []int) {
return fileDescriptor_e9ac6287ce250c9a, []int{25} return fileDescriptor_e9ac6287ce250c9a, []int{26}
} }
func (m *BlockSequences) XXX_Unmarshal(b []byte) error { func (m *BlockSequences) XXX_Unmarshal(b []byte) error {
...@@ -1432,7 +1471,7 @@ func (m *ParaChainBlockDetail) Reset() { *m = ParaChainBlockDetail{} } ...@@ -1432,7 +1471,7 @@ func (m *ParaChainBlockDetail) Reset() { *m = ParaChainBlockDetail{} }
func (m *ParaChainBlockDetail) String() string { return proto.CompactTextString(m) } func (m *ParaChainBlockDetail) String() string { return proto.CompactTextString(m) }
func (*ParaChainBlockDetail) ProtoMessage() {} func (*ParaChainBlockDetail) ProtoMessage() {}
func (*ParaChainBlockDetail) Descriptor() ([]byte, []int) { func (*ParaChainBlockDetail) Descriptor() ([]byte, []int) {
return fileDescriptor_e9ac6287ce250c9a, []int{26} return fileDescriptor_e9ac6287ce250c9a, []int{27}
} }
func (m *ParaChainBlockDetail) XXX_Unmarshal(b []byte) error { func (m *ParaChainBlockDetail) XXX_Unmarshal(b []byte) error {
...@@ -1472,6 +1511,7 @@ func init() { ...@@ -1472,6 +1511,7 @@ func init() {
proto.RegisterType((*Block)(nil), "types.Block") proto.RegisterType((*Block)(nil), "types.Block")
proto.RegisterType((*Blocks)(nil), "types.Blocks") proto.RegisterType((*Blocks)(nil), "types.Blocks")
proto.RegisterType((*BlockSeqCB)(nil), "types.BlockSeqCB") proto.RegisterType((*BlockSeqCB)(nil), "types.BlockSeqCB")
proto.RegisterType((*BlockSeqCBs)(nil), "types.BlockSeqCBs")
proto.RegisterType((*BlockSeq)(nil), "types.BlockSeq") proto.RegisterType((*BlockSeq)(nil), "types.BlockSeq")
proto.RegisterType((*BlockPid)(nil), "types.BlockPid") proto.RegisterType((*BlockPid)(nil), "types.BlockPid")
proto.RegisterType((*BlockDetails)(nil), "types.BlockDetails") proto.RegisterType((*BlockDetails)(nil), "types.BlockDetails")
...@@ -1500,73 +1540,74 @@ func init() { ...@@ -1500,73 +1540,74 @@ func init() {
func init() { proto.RegisterFile("blockchain.proto", fileDescriptor_e9ac6287ce250c9a) } func init() { proto.RegisterFile("blockchain.proto", fileDescriptor_e9ac6287ce250c9a) }
var fileDescriptor_e9ac6287ce250c9a = []byte{ var fileDescriptor_e9ac6287ce250c9a = []byte{
// 1085 bytes of a gzipped FileDescriptorProto // 1097 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x56, 0xdf, 0x6f, 0xe3, 0xc4, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x56, 0x5f, 0x6f, 0xe3, 0x44,
0x13, 0x97, 0xf3, 0xab, 0xc9, 0x24, 0xcd, 0xb7, 0xdf, 0x55, 0x40, 0xd6, 0x09, 0xb8, 0xdc, 0x72, 0x10, 0x97, 0xf3, 0xaf, 0xc9, 0x24, 0x0d, 0xbd, 0x55, 0x40, 0x51, 0x05, 0x5c, 0x6e, 0x39, 0x1d,
0x3a, 0x45, 0xc7, 0x29, 0x95, 0x5a, 0x04, 0xf7, 0x00, 0x12, 0x34, 0x45, 0x6a, 0xaf, 0xc7, 0x51, 0x51, 0x39, 0xa5, 0x52, 0x8b, 0x8e, 0x7b, 0x00, 0x09, 0x9a, 0x22, 0xb5, 0xd7, 0xe3, 0x28, 0xdb,
0xb6, 0xbd, 0x3e, 0xf0, 0xb6, 0xb5, 0xb7, 0xb5, 0xd5, 0xf8, 0x47, 0xbd, 0xeb, 0x10, 0xf3, 0x3f, 0x5e, 0x1f, 0x78, 0xdb, 0xda, 0xdb, 0xda, 0x6a, 0xfc, 0xa7, 0xde, 0x75, 0x88, 0xf9, 0x0e, 0x7c,
0xf0, 0x57, 0xf0, 0x86, 0xf8, 0x23, 0xd1, 0xce, 0xae, 0x63, 0x3b, 0xb4, 0x48, 0x48, 0xbc, 0xf0, 0x0a, 0xde, 0x10, 0x1f, 0x12, 0xed, 0xec, 0x3a, 0xb6, 0x43, 0x8b, 0x84, 0xc4, 0x0b, 0x6f, 0x3b,
0xb6, 0xf3, 0x7b, 0xe6, 0x33, 0x9e, 0x19, 0xc3, 0xde, 0xf5, 0x32, 0xf1, 0xee, 0xbc, 0x80, 0x87, 0xff, 0x67, 0x7e, 0xe3, 0x99, 0x31, 0xec, 0x5c, 0x2f, 0x62, 0xf7, 0xce, 0xf5, 0x79, 0x10, 0xcd,
0xf1, 0x3c, 0xcd, 0x12, 0x95, 0x90, 0xae, 0x2a, 0x52, 0x21, 0x9f, 0xfc, 0x5f, 0x65, 0x3c, 0x96, 0x92, 0x34, 0x56, 0x31, 0x69, 0xab, 0x3c, 0x11, 0x72, 0xf7, 0x89, 0x4a, 0x79, 0x24, 0xb9, 0xab,
0xdc, 0x53, 0x61, 0x62, 0x25, 0x4f, 0x46, 0x5e, 0x12, 0x45, 0x25, 0x45, 0xff, 0x68, 0x41, 0xef, 0x82, 0xd8, 0x4a, 0x76, 0x07, 0x6e, 0x1c, 0x86, 0x05, 0x45, 0xff, 0x6c, 0x40, 0xe7, 0x44, 0x70,
0x44, 0x70, 0x5f, 0x64, 0xc4, 0x85, 0x9d, 0x95, 0xc8, 0x64, 0x98, 0xc4, 0xae, 0x33, 0x75, 0x66, 0x4f, 0xa4, 0x64, 0x0c, 0x5b, 0x4b, 0x91, 0xca, 0x20, 0x8e, 0xc6, 0xce, 0xc4, 0x99, 0x36, 0x59,
0x6d, 0x56, 0x92, 0xe4, 0x13, 0x80, 0x94, 0x67, 0x22, 0x56, 0x27, 0x5c, 0x06, 0x6e, 0x6b, 0xea, 0x41, 0x92, 0x4f, 0x01, 0x12, 0x9e, 0x8a, 0x48, 0x9d, 0x70, 0xe9, 0x8f, 0x1b, 0x13, 0x67, 0x3a,
0xcc, 0x46, 0xac, 0xc6, 0x21, 0x1f, 0x42, 0x4f, 0xad, 0x51, 0xd6, 0x46, 0x99, 0xa5, 0xc8, 0x47, 0x60, 0x15, 0x0e, 0xf9, 0x08, 0x3a, 0x6a, 0x85, 0xb2, 0x26, 0xca, 0x2c, 0x45, 0x3e, 0x86, 0x9e,
0x30, 0x90, 0x8a, 0x2b, 0x81, 0xa2, 0x0e, 0x8a, 0x2a, 0x86, 0xb6, 0x0a, 0x44, 0x78, 0x1b, 0x28, 0x54, 0x5c, 0x09, 0x14, 0xb5, 0x50, 0x54, 0x32, 0xb4, 0x95, 0x2f, 0x82, 0x5b, 0x5f, 0x8d, 0xdb,
0xb7, 0x8b, 0xe1, 0x2c, 0xa5, 0xad, 0xb0, 0x9c, 0xcb, 0x30, 0x12, 0x6e, 0x0f, 0x45, 0x15, 0x43, 0x18, 0xce, 0x52, 0xda, 0x0a, 0xcb, 0xb9, 0x0c, 0x42, 0x31, 0xee, 0xa0, 0xa8, 0x64, 0xe8, 0x2c,
0x67, 0xa9, 0xd6, 0x8b, 0x24, 0x8f, 0x95, 0x3b, 0x30, 0x59, 0x5a, 0x92, 0x10, 0xe8, 0x04, 0x3a, 0xd5, 0x6a, 0x1e, 0x67, 0x91, 0x1a, 0xf7, 0x4c, 0x96, 0x96, 0x24, 0x04, 0x5a, 0xbe, 0x0e, 0x04,
0x10, 0x60, 0x20, 0x7c, 0xeb, 0xcc, 0xfd, 0xf0, 0xe6, 0x26, 0xf4, 0xf2, 0xa5, 0x2a, 0xdc, 0xe1, 0x18, 0x08, 0xdf, 0x3a, 0x73, 0x2f, 0xb8, 0xb9, 0x09, 0xdc, 0x6c, 0xa1, 0xf2, 0x71, 0x7f, 0xe2,
0xd4, 0x99, 0xed, 0xb2, 0x1a, 0x87, 0xcc, 0x61, 0x20, 0xc3, 0xdb, 0x98, 0xab, 0x3c, 0x13, 0x6e, 0x4c, 0xb7, 0x59, 0x85, 0x43, 0x66, 0xd0, 0x93, 0xc1, 0x6d, 0xc4, 0x55, 0x96, 0x8a, 0x71, 0x77,
0x7f, 0xea, 0xcc, 0x86, 0x07, 0x7b, 0x73, 0x84, 0x6e, 0x7e, 0x51, 0xf2, 0x59, 0xa5, 0x42, 0x7f, 0xe2, 0x4c, 0xfb, 0x07, 0x3b, 0x33, 0x84, 0x6e, 0x76, 0x51, 0xf0, 0x59, 0xa9, 0x42, 0x7f, 0x6f,
0x6b, 0x41, 0xf7, 0x48, 0xe7, 0xf2, 0x1f, 0x41, 0xeb, 0x5f, 0xae, 0x9f, 0x3c, 0x87, 0xb6, 0x5a, 0x40, 0xfb, 0x48, 0xe7, 0xf2, 0x3f, 0x41, 0xeb, 0x3f, 0xae, 0x9f, 0x3c, 0x87, 0xa6, 0x5a, 0xc9,
0x4b, 0x77, 0x67, 0xda, 0x9e, 0x0d, 0x0f, 0x88, 0xd5, 0xbc, 0xac, 0xbe, 0x31, 0xa6, 0xc5, 0xf4, 0xf1, 0xd6, 0xa4, 0x39, 0xed, 0x1f, 0x10, 0xab, 0x79, 0x59, 0x7e, 0x63, 0x4c, 0x8b, 0xe9, 0x4b,
0x15, 0xf4, 0x10, 0x24, 0x49, 0x28, 0x74, 0x43, 0x25, 0x22, 0xe9, 0x3a, 0x68, 0x31, 0xb2, 0x16, 0xe8, 0x20, 0x48, 0x92, 0x50, 0x68, 0x07, 0x4a, 0x84, 0x72, 0xec, 0xa0, 0xc5, 0xc0, 0x5a, 0xa0,
0x28, 0x65, 0x46, 0x44, 0xdf, 0x00, 0x20, 0x7d, 0x21, 0xee, 0x17, 0x47, 0xba, 0x8b, 0x31, 0x8f, 0x94, 0x19, 0x11, 0x7d, 0x03, 0x80, 0xf4, 0x85, 0xb8, 0x9f, 0x1f, 0xe9, 0x2e, 0x46, 0x3c, 0x14,
0x04, 0x82, 0x3a, 0x60, 0xf8, 0x26, 0x7b, 0xd0, 0x7e, 0xcf, 0xde, 0x22, 0x94, 0x03, 0xa6, 0x9f, 0x08, 0x6a, 0x8f, 0xe1, 0x9b, 0xec, 0x40, 0xf3, 0x3d, 0x7b, 0x8b, 0x50, 0xf6, 0x98, 0x7e, 0x6a,
0x1a, 0x0d, 0x11, 0x7b, 0x89, 0x2f, 0x10, 0xc3, 0x01, 0xb3, 0x14, 0x4d, 0xa1, 0x5f, 0xfa, 0xd2, 0x34, 0x44, 0xe4, 0xc6, 0x9e, 0x40, 0x0c, 0x7b, 0xcc, 0x52, 0xf4, 0x15, 0xf4, 0x4b, 0x5f, 0x92,
0x56, 0x71, 0x1e, 0xd9, 0xee, 0xe8, 0x27, 0x79, 0x01, 0x6d, 0x29, 0xee, 0xd1, 0xcf, 0xf0, 0x60, 0x7c, 0x5e, 0x0f, 0xff, 0xa4, 0x1a, 0x1e, 0x55, 0x8a, 0x1c, 0x12, 0xe8, 0x16, 0x4c, 0x1d, 0x2d,
0x52, 0xcf, 0xe5, 0x42, 0xdc, 0xe7, 0x22, 0xf6, 0x04, 0xd3, 0x0a, 0xe4, 0x25, 0xf4, 0x7c, 0xa1, 0xca, 0x42, 0xdb, 0x55, 0xfd, 0x24, 0x2f, 0xa0, 0x29, 0xc5, 0x3d, 0xc6, 0xef, 0x1f, 0x8c, 0x36,
0x78, 0xb8, 0x44, 0xef, 0x55, 0xa1, 0xa8, 0x7a, 0x8c, 0x12, 0x66, 0x35, 0xe8, 0x37, 0x36, 0xe2, 0x9c, 0x64, 0x22, 0x72, 0x05, 0xd3, 0x0a, 0x64, 0x0f, 0x3a, 0x9e, 0x50, 0x3c, 0x58, 0x60, 0x56,
0x79, 0xe8, 0xeb, 0x88, 0x69, 0xe8, 0xdb, 0xd4, 0xf5, 0x53, 0xd7, 0x8f, 0xcd, 0xb0, 0x31, 0xb7, 0x25, 0x40, 0xa8, 0x7a, 0x8c, 0x12, 0x66, 0x35, 0xe8, 0xb7, 0x36, 0xe2, 0x79, 0xe0, 0xe9, 0x88,
0xea, 0x47, 0x11, 0x7d, 0x0d, 0xa3, 0x9a, 0x63, 0x49, 0x66, 0x4d, 0xcc, 0x1e, 0x0a, 0x6e, 0x91, 0x49, 0xe0, 0xd9, 0x92, 0xf5, 0x53, 0xe3, 0x86, 0x4d, 0xb4, 0x31, 0x37, 0x70, 0x43, 0x11, 0x7d,
0x9b, 0xc3, 0x8e, 0x99, 0x5d, 0x49, 0x3e, 0x6d, 0x1a, 0xed, 0x5a, 0x23, 0x23, 0x2e, 0xf5, 0x4f, 0x0d, 0x83, 0x8a, 0x63, 0x49, 0xa6, 0xf5, 0x62, 0x1f, 0x0a, 0x6e, 0xab, 0x9d, 0xc1, 0x96, 0x99,
0x00, 0xac, 0xfe, 0xc3, 0xd9, 0xce, 0x60, 0x27, 0x30, 0x72, 0x9b, 0xef, 0xb8, 0xe1, 0x46, 0xb2, 0x79, 0x49, 0x3e, 0xab, 0x1b, 0x6d, 0x5b, 0x23, 0x23, 0x2e, 0xf4, 0x4f, 0x00, 0xac, 0xfe, 0xc3,
0x52, 0x4c, 0x03, 0xd8, 0xc5, 0x7c, 0x7e, 0x58, 0x89, 0x6c, 0x15, 0x8a, 0x9f, 0xc9, 0x33, 0xe8, 0xd9, 0x4e, 0x61, 0xcb, 0x37, 0x72, 0x9b, 0xef, 0xb0, 0xe6, 0x46, 0xb2, 0x42, 0x4c, 0x7d, 0xd8,
0x68, 0x19, 0x7a, 0xfb, 0x4b, 0x78, 0x14, 0xd5, 0x27, 0xb7, 0xd5, 0x9c, 0xdc, 0x27, 0xd0, 0x37, 0xc6, 0x7c, 0x7e, 0x5c, 0x8a, 0x74, 0x19, 0x88, 0x5f, 0xc8, 0x33, 0x68, 0x69, 0x19, 0x7a, 0xfb,
0x33, 0x20, 0xa4, 0xdb, 0x9e, 0xb6, 0x67, 0x23, 0xb6, 0xa1, 0xe9, 0xef, 0x0e, 0x0c, 0x6b, 0xa5, 0x5b, 0x78, 0x14, 0x55, 0x27, 0xbe, 0x51, 0x9f, 0xf8, 0x5d, 0xe8, 0x9a, 0xd9, 0x11, 0x72, 0xdc,
0x57, 0x88, 0x3a, 0x8f, 0x22, 0x4a, 0xe6, 0xd0, 0xcf, 0x84, 0x27, 0xc2, 0x54, 0xe9, 0x42, 0xea, 0x9c, 0x34, 0xa7, 0x03, 0xb6, 0xa6, 0xe9, 0x1f, 0x8e, 0xfd, 0x14, 0x4c, 0xe9, 0x25, 0xa2, 0xce,
0x20, 0x32, 0xc3, 0x3e, 0xe6, 0x8a, 0xb3, 0x8d, 0x0e, 0x79, 0x0a, 0xad, 0xb3, 0x2b, 0x8c, 0x3c, 0xa3, 0x88, 0x92, 0x19, 0x74, 0x53, 0xe1, 0x8a, 0x20, 0x51, 0xba, 0x90, 0x2a, 0x88, 0xcc, 0xb0,
0x3c, 0xf8, 0x9f, 0xd5, 0x3c, 0x13, 0xc5, 0x15, 0x5f, 0xe6, 0x82, 0xb5, 0xce, 0xae, 0xc8, 0x0b, 0x8f, 0xb9, 0xe2, 0x6c, 0xad, 0x43, 0x9e, 0x42, 0xe3, 0xec, 0x0a, 0x23, 0xf7, 0x0f, 0x3e, 0xb0,
0x18, 0xa7, 0x99, 0x58, 0x5d, 0x28, 0xae, 0x72, 0x59, 0x9b, 0xcf, 0x2d, 0x2e, 0xfd, 0x02, 0xfa, 0x9a, 0x67, 0x22, 0xbf, 0xe2, 0x8b, 0x4c, 0xb0, 0xc6, 0xd9, 0x15, 0x79, 0x01, 0xc3, 0x24, 0x15,
0xac, 0x74, 0xfa, 0xb2, 0x96, 0x84, 0x69, 0xca, 0xb8, 0x99, 0x44, 0x95, 0x00, 0x7d, 0x03, 0x83, 0xcb, 0x0b, 0xc5, 0x55, 0x26, 0x2b, 0x73, 0xbd, 0xc1, 0xa5, 0xaf, 0xa0, 0xcb, 0x0a, 0xa7, 0x7b,
0xf3, 0x2c, 0x5c, 0x71, 0xaf, 0x38, 0xbb, 0x22, 0x5f, 0xeb, 0x60, 0x96, 0xb8, 0x4c, 0xee, 0x44, 0x95, 0x24, 0x4c, 0x53, 0x86, 0xf5, 0x24, 0xca, 0x04, 0xe8, 0x1b, 0xe8, 0x9d, 0xa7, 0xc1, 0x92,
0x6c, 0xcd, 0x3f, 0xb0, 0xe6, 0xe7, 0x0d, 0x21, 0xdb, 0x52, 0xa6, 0x05, 0x8c, 0x9b, 0x1a, 0x64, 0xbb, 0xf9, 0xd9, 0x15, 0xf9, 0x46, 0x07, 0xb3, 0xc4, 0x65, 0x7c, 0x27, 0x22, 0x6b, 0xfe, 0xa1,
0x02, 0x5d, 0x65, 0xfd, 0xe8, 0x56, 0x1b, 0xc2, 0xb4, 0xe3, 0x34, 0xf6, 0xc5, 0x1a, 0xdb, 0xd1, 0x35, 0x3f, 0xaf, 0x09, 0xd9, 0x86, 0x32, 0xcd, 0x61, 0x58, 0xd7, 0x20, 0x23, 0x68, 0x2b, 0xeb,
0x65, 0x25, 0x69, 0x16, 0x54, 0xd0, 0x58, 0x50, 0xb8, 0x4c, 0x0d, 0x4c, 0x9d, 0x47, 0x61, 0xa2, 0x47, 0xb7, 0xda, 0x10, 0xa6, 0x1d, 0xa7, 0x91, 0x27, 0x56, 0xd8, 0x8e, 0x36, 0x2b, 0x48, 0xb3,
0x12, 0x26, 0x65, 0xf9, 0xdf, 0xc6, 0x7e, 0x55, 0xd1, 0x67, 0x0d, 0x28, 0x9c, 0x9a, 0x79, 0xa9, 0xd8, 0xfc, 0xda, 0x62, 0xc3, 0x25, 0x6c, 0x60, 0x6a, 0x3d, 0x0a, 0x13, 0x95, 0x30, 0x2a, 0xca,
0x5e, 0x6b, 0xc6, 0x1c, 0x06, 0x9b, 0x8a, 0xec, 0x67, 0xb8, 0xb7, 0x5d, 0x39, 0xab, 0x54, 0xe8, 0xff, 0x2e, 0xf2, 0xca, 0x8a, 0xbe, 0xa8, 0x41, 0xe1, 0x54, 0xcc, 0x0b, 0xf5, 0x4a, 0x33, 0x66,
0x0c, 0x88, 0xf5, 0xb2, 0x08, 0x84, 0x77, 0x77, 0xb9, 0x7e, 0x1b, 0x4a, 0x3c, 0x06, 0x22, 0xcb, 0xd0, 0x5b, 0x57, 0x64, 0x3f, 0xc3, 0x9d, 0xcd, 0xca, 0x59, 0xa9, 0x42, 0xa7, 0x40, 0xac, 0x97,
0x0c, 0xf2, 0x03, 0x86, 0x6f, 0x5a, 0xc0, 0x70, 0xa1, 0x4f, 0xa4, 0x69, 0x18, 0x79, 0x0e, 0xbb, 0xb9, 0x2f, 0xdc, 0xbb, 0xcb, 0xd5, 0xdb, 0x40, 0xe2, 0x11, 0x11, 0x69, 0x6a, 0x90, 0xef, 0x31,
0x5e, 0x9e, 0xe1, 0x5a, 0x36, 0x8b, 0xd5, 0x6c, 0x8a, 0x26, 0x93, 0x4c, 0x61, 0x18, 0x89, 0x28, 0x7c, 0xd3, 0x1c, 0xfa, 0x73, 0x7d, 0x5a, 0x4d, 0xc3, 0xc8, 0x73, 0xd8, 0x76, 0xb3, 0x14, 0xd7,
0x4d, 0x92, 0xe5, 0x45, 0xf8, 0x8b, 0xb0, 0x5f, 0x6e, 0x9d, 0x45, 0x28, 0x8c, 0x22, 0x79, 0xfb, 0xb9, 0x59, 0xc8, 0x66, 0x53, 0xd4, 0x99, 0x64, 0x02, 0xfd, 0x50, 0x84, 0x49, 0x1c, 0x2f, 0x2e,
0x63, 0x2e, 0x72, 0x81, 0x2a, 0x6d, 0x54, 0x69, 0xf0, 0x28, 0x87, 0x01, 0x13, 0xf7, 0x76, 0x29, 0x82, 0x5f, 0x85, 0xfd, 0x72, 0xab, 0x2c, 0x42, 0x61, 0x10, 0xca, 0xdb, 0x9f, 0x32, 0x91, 0x09,
0x4e, 0xa0, 0x2b, 0x15, 0xcf, 0xca, 0x80, 0x86, 0xd0, 0xe3, 0x28, 0x62, 0xdf, 0x06, 0xd0, 0x4f, 0x54, 0x69, 0xa2, 0x4a, 0x8d, 0x47, 0x39, 0xf4, 0x98, 0xb8, 0xb7, 0xcb, 0x74, 0x04, 0x6d, 0xa9,
0x3d, 0x16, 0xa1, 0x3c, 0xae, 0x16, 0x51, 0x9f, 0x6d, 0xe8, 0x72, 0x78, 0x3b, 0x58, 0x9e, 0x7e, 0x78, 0x5a, 0x04, 0x34, 0x84, 0x1e, 0x47, 0x11, 0x79, 0x36, 0x80, 0x7e, 0xea, 0xb1, 0x08, 0xe4,
0xd2, 0x67, 0x30, 0xfc, 0xbe, 0x96, 0x15, 0x81, 0x8e, 0xd4, 0xd9, 0x98, 0x18, 0xf8, 0xa6, 0x2f, 0x71, 0xb9, 0x88, 0xba, 0x6c, 0x4d, 0x17, 0xc3, 0xdb, 0xc2, 0xf2, 0xf4, 0x93, 0x3e, 0x83, 0xfe,
0x61, 0x8f, 0x89, 0x74, 0x59, 0x60, 0x1e, 0xb6, 0xbe, 0xea, 0xae, 0x38, 0xf5, 0xbb, 0xa2, 0x33, 0x0f, 0x95, 0xac, 0x08, 0xb4, 0xa4, 0xce, 0xc6, 0xc4, 0xc0, 0x37, 0xdd, 0x83, 0x1d, 0x26, 0x92,
0x46, 0xb5, 0xa3, 0xc4, 0x2f, 0xca, 0xb5, 0xef, 0xfc, 0xed, 0xda, 0xff, 0xa7, 0x63, 0x47, 0x5f, 0x45, 0x8e, 0x79, 0xd8, 0xfa, 0xca, 0x7b, 0xe4, 0x54, 0xef, 0x91, 0xce, 0x18, 0xd5, 0x8e, 0x62,
0x01, 0x9c, 0xca, 0x05, 0xcf, 0x6f, 0x03, 0xf5, 0x3e, 0xd5, 0xa7, 0xea, 0x54, 0x7a, 0x48, 0xe5, 0x2f, 0x2f, 0xce, 0x85, 0xf3, 0x8f, 0xe7, 0xe2, 0xdf, 0x8e, 0x1d, 0x7d, 0x09, 0x70, 0x2a, 0xe7,
0x29, 0x26, 0xd3, 0x67, 0x35, 0x0e, 0x7d, 0x0d, 0xe3, 0x53, 0xf9, 0x4e, 0xa5, 0x0b, 0xdc, 0xd7, 0x3c, 0xbb, 0xf5, 0xd5, 0xfb, 0x44, 0x9f, 0xb8, 0x53, 0xe9, 0x22, 0x95, 0x25, 0x98, 0x4c, 0x97,
0x45, 0xec, 0xe9, 0xa9, 0x0c, 0x65, 0xac, 0x52, 0x0f, 0x61, 0x2d, 0x62, 0xcf, 0x5a, 0x6d, 0x71, 0x55, 0x38, 0xf4, 0x35, 0x0c, 0x4f, 0xe5, 0x3b, 0x95, 0xcc, 0x71, 0x5f, 0xe7, 0x91, 0xab, 0xa7,
0xe9, 0xaf, 0x0e, 0xec, 0x62, 0xe3, 0xbf, 0x5b, 0x0b, 0x2f, 0x57, 0x49, 0xa6, 0x8b, 0xf6, 0xb3, 0x32, 0x90, 0x91, 0x4a, 0x5c, 0x84, 0x35, 0x8f, 0x5c, 0x6b, 0xb5, 0xc1, 0xa5, 0xbf, 0x39, 0xb0,
0x70, 0x25, 0x32, 0x3b, 0x12, 0x96, 0xd2, 0x88, 0xdf, 0xe4, 0xb1, 0xf7, 0x4e, 0x1f, 0x20, 0x73, 0x8d, 0x8d, 0xff, 0x7e, 0x25, 0xdc, 0x4c, 0xc5, 0xa9, 0x2e, 0xda, 0x4b, 0x83, 0xa5, 0x48, 0xed,
0x6d, 0x36, 0x74, 0xf3, 0x3c, 0xb7, 0xb7, 0xcf, 0xf3, 0x04, 0xba, 0x29, 0xcf, 0x78, 0x64, 0x17, 0x48, 0x58, 0x4a, 0x23, 0x7e, 0x93, 0x45, 0xee, 0x3b, 0x7d, 0xb8, 0xcc, 0x95, 0x5a, 0xd3, 0xf5,
0x83, 0x21, 0x34, 0x57, 0xac, 0x55, 0xc6, 0xf1, 0x66, 0x8f, 0x98, 0x21, 0xe8, 0x97, 0x76, 0x79, 0xb3, 0xde, 0xdc, 0x3c, 0xeb, 0x23, 0x68, 0x27, 0x3c, 0xe5, 0xa1, 0x5d, 0x0c, 0x86, 0xd0, 0x5c,
0x96, 0x47, 0x47, 0xf7, 0x0a, 0xbd, 0x3a, 0xe6, 0xcf, 0x05, 0x1d, 0x12, 0xe8, 0x5c, 0x16, 0x69, 0xb1, 0x52, 0x29, 0xc7, 0x5b, 0x3f, 0x60, 0x86, 0xa0, 0x5f, 0xd9, 0xe5, 0x59, 0x1c, 0x1d, 0xdd,
0xf9, 0xc1, 0xe1, 0x9b, 0x7e, 0x05, 0xe3, 0x86, 0xa1, 0x5e, 0x32, 0x8d, 0xb5, 0xff, 0xf0, 0x4d, 0x2b, 0xf4, 0xea, 0x98, 0x3f, 0x1e, 0x74, 0x48, 0xa0, 0x75, 0x99, 0x27, 0xc5, 0x07, 0x87, 0x6f,
0xb3, 0xdb, 0x3f, 0x80, 0xc9, 0x39, 0xcf, 0x38, 0x22, 0x51, 0xdf, 0xa8, 0x9f, 0xc3, 0x10, 0xd7, 0xfa, 0x35, 0x0c, 0x6b, 0x86, 0x7a, 0xc9, 0xd4, 0xd6, 0xfe, 0xc3, 0x37, 0xcd, 0x6e, 0x7f, 0x1f,
0xa6, 0x3d, 0x79, 0xce, 0xa3, 0x27, 0xaf, 0xae, 0xa6, 0xa1, 0x92, 0x36, 0x80, 0xcd, 0x71, 0x43, 0x46, 0xe7, 0x3c, 0xe5, 0x88, 0x44, 0x75, 0xa3, 0x7e, 0x09, 0x7d, 0x5c, 0x9b, 0xf6, 0xe4, 0x39,
0x1f, 0x3d, 0xfd, 0xe9, 0xe3, 0xdb, 0x50, 0x05, 0xf9, 0xf5, 0xdc, 0x4b, 0xa2, 0xfd, 0xc3, 0x43, 0x8f, 0x9e, 0xbc, 0xaa, 0x9a, 0x86, 0x4a, 0xda, 0x00, 0x36, 0xc7, 0x35, 0x7d, 0xf4, 0xf4, 0xe7,
0x2f, 0xde, 0xc7, 0x7f, 0xd3, 0xc3, 0xc3, 0x7d, 0xf4, 0x7a, 0xdd, 0xc3, 0x9f, 0xcf, 0xc3, 0x3f, 0x4f, 0x6e, 0x03, 0xe5, 0x67, 0xd7, 0x33, 0x37, 0x0e, 0xf7, 0x0f, 0x0f, 0xdd, 0x68, 0x1f, 0xff,
0x03, 0x00, 0x00, 0xff, 0xff, 0x97, 0x32, 0x81, 0xf9, 0xb8, 0x0a, 0x00, 0x00, 0x69, 0x0f, 0x0f, 0xf7, 0xd1, 0xeb, 0x75, 0x07, 0x7f, 0x5a, 0x0f, 0xff, 0x0a, 0x00, 0x00, 0xff,
0xff, 0x23, 0x1c, 0x7b, 0x8c, 0xf0, 0x0a, 0x00, 0x00,
} }
...@@ -142,6 +142,9 @@ type RPC struct { ...@@ -142,6 +142,9 @@ type RPC struct {
JrpcFuncBlacklist []string `protobuf:"bytes,7,rep,name=jrpcFuncBlacklist" json:"jrpcFuncBlacklist,omitempty"` JrpcFuncBlacklist []string `protobuf:"bytes,7,rep,name=jrpcFuncBlacklist" json:"jrpcFuncBlacklist,omitempty"`
GrpcFuncBlacklist []string `protobuf:"bytes,8,rep,name=grpcFuncBlacklist" json:"grpcFuncBlacklist,omitempty"` GrpcFuncBlacklist []string `protobuf:"bytes,8,rep,name=grpcFuncBlacklist" json:"grpcFuncBlacklist,omitempty"`
MainnetJrpcAddr string `protobuf:"bytes,9,opt,name=mainnetJrpcAddr" json:"mainnetJrpcAddr,omitempty"` MainnetJrpcAddr string `protobuf:"bytes,9,opt,name=mainnetJrpcAddr" json:"mainnetJrpcAddr,omitempty"`
EnableTLS bool `protobuf:"varint,10,opt,name=enableTLS" json:"enableTLS,omitempty"`
CertFile string `protobuf:"varint,11,opt,name=certFile" json:"certFile,omitempty"`
KeyFile string `protobuf:"varint,12,opt,name=keyFile" json:"keyFile,omitempty"`
} }
// Exec 配置 // Exec 配置
......
...@@ -136,6 +136,9 @@ const ( ...@@ -136,6 +136,9 @@ const (
EventWalletCreateTx = 129 EventWalletCreateTx = 129
EventStoreList = 130 EventStoreList = 130
EventStoreListReply = 131 EventStoreListReply = 131
EventListBlockSeqCB = 132
EventGetSeqCBLastNum = 133
//exec //exec
EventBlockChainQuery = 212 EventBlockChainQuery = 212
EventConsensusQuery = 213 EventConsensusQuery = 213
......
...@@ -12,7 +12,7 @@ import ( ...@@ -12,7 +12,7 @@ import (
"unicode" "unicode"
"github.com/33cn/chain33/common/address" "github.com/33cn/chain33/common/address"
proto "github.com/golang/protobuf/proto" "github.com/golang/protobuf/proto"
) )
func init() { func init() {
...@@ -113,17 +113,37 @@ func CallExecNewTx(execName, action string, param interface{}) ([]byte, error) { ...@@ -113,17 +113,37 @@ func CallExecNewTx(execName, action string, param interface{}) ([]byte, error) {
func CallCreateTx(execName, action string, param Message) ([]byte, error) { func CallCreateTx(execName, action string, param Message) ([]byte, error) {
exec := LoadExecutorType(execName) exec := LoadExecutorType(execName)
if exec == nil { if exec == nil {
tlog.Error("callExecNewTx", "Error", "exec not found") tlog.Error("CallCreateTx", "Error", "exec not found")
return nil, ErrNotSupport return nil, ErrNotSupport
} }
// param is interface{type, var-nil}, check with nil always fail // param is interface{type, var-nil}, check with nil always fail
if param == nil { if param == nil {
tlog.Error("callExecNewTx", "Error", "param in nil") tlog.Error("CallCreateTx", "Error", "param in nil")
return nil, ErrInvalidParam return nil, ErrInvalidParam
} }
tx, err := exec.Create(action, param) tx, err := exec.Create(action, param)
if err != nil { if err != nil {
tlog.Error("callExecNewTx", "Error", err) tlog.Error("CallCreateTx", "Error", err)
return nil, err
}
return FormatTxEncode(execName, tx)
}
//CallCreateTxJSON create tx by json
func CallCreateTxJSON(execName, action string, param json.RawMessage) ([]byte, error) {
exec := LoadExecutorType(execName)
if exec == nil {
tlog.Error("CallCreateTxJSON", "Error", "exec not found")
return nil, ErrNotSupport
}
// param is interface{type, var-nil}, check with nil always fail
if param == nil {
tlog.Error("CallCreateTxJSON", "Error", "param in nil")
return nil, ErrInvalidParam
}
tx, err := exec.CreateTx(action, param)
if err != nil {
tlog.Error("CallCreateTxJSON", "Error", err)
return nil, err return nil, err
} }
return FormatTxEncode(execName, tx) return FormatTxEncode(execName, tx)
...@@ -655,7 +675,7 @@ func (base *ExecTypeBase) GetAction(action string) (Message, error) { ...@@ -655,7 +675,7 @@ func (base *ExecTypeBase) GetAction(action string) (Message, error) {
return nil, ErrActionNotSupport return nil, ErrActionNotSupport
} }
//CreateTx 构造tx交易重构完成后删除 //CreateTx 通过json rpc 创建交易
func (base *ExecTypeBase) CreateTx(action string, msg json.RawMessage) (*Transaction, error) { func (base *ExecTypeBase) CreateTx(action string, msg json.RawMessage) (*Transaction, error) {
data, err := base.GetAction(action) data, err := base.GetAction(action)
if err != nil { if err != nil {
...@@ -714,7 +734,10 @@ func (base *ExecTypeBase) CreateTransaction(action string, data Message) (tx *Tr ...@@ -714,7 +734,10 @@ func (base *ExecTypeBase) CreateTransaction(action string, data Message) (tx *Tr
tymap := base.child.GetTypeMap() tymap := base.child.GetTypeMap()
if tyid, ok := tymap[action]; ok { if tyid, ok := tymap[action]; ok {
field.Set(reflect.ValueOf(tyid)) field.Set(reflect.ValueOf(tyid))
return &Transaction{Payload: Encode(value)}, nil tx := &Transaction{
Payload: Encode(value),
}
return tx, nil
} }
return nil, ErrActionNotSupport return nil, ErrActionNotSupport
} }
......
// Copyright Fuzamei Corp. 2018 All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package types
import (
"encoding/json"
"testing"
"github.com/stretchr/testify/assert"
)
func TestLoadExecutorType(t *testing.T) {
exec := LoadExecutorType("manage")
assert.NotEqual(t, exec, nil)
assert.Equal(t, exec.GetName(), "manage")
exec = LoadExecutorType("coins")
assert.NotEqual(t, exec, nil)
assert.Equal(t, exec.GetName(), "coins")
exec = LoadExecutorType("xxxx")
assert.Equal(t, exec, nil)
}
func TestFormatTx(t *testing.T) {
tx := &Transaction{
Payload: []byte("this is a test."),
}
tx, err := FormatTx("user.p.none", tx)
assert.Equal(t, err, nil)
assert.Equal(t, tx.Execer, []byte("user.p.none"))
fee, _ := tx.GetRealFee(GInt("MinFee"))
assert.Equal(t, tx.Fee, fee)
}
func TestFormatTxEncode(t *testing.T) {
data, err := FormatTxEncode("coins", &Transaction{
Payload: []byte("this is a test."),
})
assert.Equal(t, err, nil)
var tx Transaction
err = Decode(data, &tx)
assert.Equal(t, err, nil)
assert.Equal(t, tx.Execer, []byte("coins"))
}
func TestCallCreateTxJSON(t *testing.T) {
modify := &ModifyConfig{
Key: "token-finisher",
Value: "xxxxxxxxxxxxxxxxxxxxxxxxxxxx",
Op: "add",
Addr: "",
}
data, err := json.Marshal(modify)
assert.Equal(t, err, nil)
result, err := CallCreateTxJSON("manage", "Modify", data)
assert.Equal(t, err, nil)
assert.NotEqual(t, result, nil)
var tx Transaction
err = Decode(result, &tx)
assert.Equal(t, err, nil)
assert.Equal(t, tx.Execer, []byte("manage"))
fee, _ := tx.GetRealFee(GInt("MinFee"))
assert.Equal(t, tx.Fee, fee)
_, err = CallCreateTxJSON("coins", "Modify", data)
assert.NotEqual(t, err, nil)
_, err = CallCreateTxJSON("xxxx", "xxx", data)
assert.NotEqual(t, err, nil)
modify = &ModifyConfig{
Key: "token-finisher",
Value: "xxxxxxxxxxxxxxxxxxxxxxxxxxxx",
Op: "delete",
Addr: "",
}
data, err = json.Marshal(modify)
assert.Equal(t, err, nil)
result, err = CallCreateTxJSON("manage", "Modify", data)
assert.Equal(t, err, nil)
assert.NotEqual(t, result, nil)
err = Decode(result, &tx)
assert.Equal(t, err, nil)
assert.Equal(t, tx.Execer, []byte("manage"))
fee, _ = tx.GetRealFee(GInt("MinFee"))
assert.Equal(t, tx.Fee, fee)
}
func TestCallCreateTx(t *testing.T) {
modify := &ModifyConfig{
Key: "token-finisher",
Value: "xxxxxxxxxxxxxxxxxxxxxxxxxxxx",
Op: "add",
Addr: "",
}
result, err := CallCreateTx("manage", "Modify", modify)
assert.Equal(t, err, nil)
assert.NotEqual(t, result, nil)
var tx Transaction
err = Decode(result, &tx)
assert.Equal(t, err, nil)
assert.Equal(t, tx.Execer, []byte("manage"))
fee, _ := tx.GetRealFee(GInt("MinFee"))
assert.Equal(t, tx.Fee, fee)
_, err = CallCreateTx("coins", "Modify", modify)
assert.NotEqual(t, err, nil)
_, err = CallCreateTx("xxxx", "xxx", modify)
assert.NotEqual(t, err, nil)
modify = &ModifyConfig{
Key: "token-finisher",
Value: "xxxxxxxxxxxxxxxxxxxxxxxxxxxx",
Op: "delete",
Addr: "",
}
result, err = CallCreateTx("manage", "Modify", modify)
assert.Equal(t, err, nil)
assert.NotEqual(t, result, nil)
err = Decode(result, &tx)
assert.Equal(t, err, nil)
assert.Equal(t, tx.Execer, []byte("manage"))
fee, _ = tx.GetRealFee(GInt("MinFee"))
assert.Equal(t, tx.Fee, fee)
}
...@@ -50,6 +50,10 @@ message BlockSeqCB { ...@@ -50,6 +50,10 @@ message BlockSeqCB {
string encode = 3; string encode = 3;
} }
message BlockSeqCBs {
repeated BlockSeqCB items = 1;
}
message BlockSeq { message BlockSeq {
int64 num = 1; int64 num = 1;
BlockSequence seq = 2; BlockSequence seq = 2;
......
...@@ -58,6 +58,9 @@ grpcBindAddr="localhost:8802" ...@@ -58,6 +58,9 @@ grpcBindAddr="localhost:8802"
whitelist=["127.0.0.1"] whitelist=["127.0.0.1"]
jrpcFuncWhitelist=["*"] jrpcFuncWhitelist=["*"]
grpcFuncWhitelist=["*"] grpcFuncWhitelist=["*"]
enableTLS=false
certFile="cert.pem"
keyFile="key.pem"
[mempool] [mempool]
poolCacheSize=102400 poolCacheSize=102400
......
...@@ -6,7 +6,9 @@ package cli ...@@ -6,7 +6,9 @@ package cli
import ( import (
"fmt" "fmt"
"net/http"
"os" "os"
"strings"
"github.com/33cn/chain33/common/log" "github.com/33cn/chain33/common/log"
"github.com/33cn/chain33/pluginmgr" "github.com/33cn/chain33/pluginmgr"
...@@ -43,6 +45,7 @@ var closeCmd = &cobra.Command{ ...@@ -43,6 +45,7 @@ var closeCmd = &cobra.Command{
func init() { func init() {
rootCmd.AddCommand( rootCmd.AddCommand(
commands.CertCmd(),
commands.AccountCmd(), commands.AccountCmd(),
commands.BlockCmd(), commands.BlockCmd(),
commands.BTYCmd(), commands.BTYCmd(),
...@@ -60,8 +63,34 @@ func init() { ...@@ -60,8 +63,34 @@ func init() {
) )
} }
func testTLS(RPCAddr string) string {
rpcaddr := RPCAddr
if strings.HasPrefix(rpcaddr, "https://") {
return RPCAddr
}
if !strings.HasPrefix(rpcaddr, "http://") {
return RPCAddr
}
//test tls ok
if rpcaddr[len(rpcaddr)-1] != '/' {
rpcaddr += "/"
}
rpcaddr += "test"
resp, err := http.Get(rpcaddr)
if err != nil {
return "https://" + RPCAddr[7:]
}
defer resp.Body.Close()
if resp.StatusCode == 200 {
return RPCAddr
}
return "https://" + RPCAddr[7:]
}
//Run : //Run :
func Run(RPCAddr, ParaName string) { func Run(RPCAddr, ParaName string) {
//test tls is enable
RPCAddr = testTLS(RPCAddr)
pluginmgr.AddCmd(rootCmd) pluginmgr.AddCmd(rootCmd)
log.SetLogLevel("error") log.SetLogLevel("error")
types.S("RPCAddr", RPCAddr) types.S("RPCAddr", RPCAddr)
......
...@@ -135,7 +135,8 @@ func GetSeed(db dbm.DB, password string) (string, error) { ...@@ -135,7 +135,8 @@ func GetSeed(db dbm.DB, password string) (string, error) {
} }
seed, err := AesgcmDecrypter([]byte(password), Encryptedseed) seed, err := AesgcmDecrypter([]byte(password), Encryptedseed)
if err != nil { if err != nil {
return "", err seedlog.Error("GetSeed", "AesgcmDecrypter err", err)
return "", types.ErrInputPassword
} }
return string(seed), nil return string(seed), nil
} }
......
...@@ -30,16 +30,18 @@ func (wallet *Wallet) parseExpire(expire string) (int64, error) { ...@@ -30,16 +30,18 @@ func (wallet *Wallet) parseExpire(expire string) (int64, error) {
if len(expire) == 0 { if len(expire) == 0 {
return 0, errors.New("Expire string should not be empty") return 0, errors.New("Expire string should not be empty")
} }
if expire[0] == 'H' && expire[1] == ':' { if expire[0] == 'H' && expire[1] == ':' {
txHeight, err := strconv.ParseInt(expire[2:], 10, 64) txHeight, err := strconv.ParseInt(expire[2:], 10, 64)
if err != nil { if err != nil {
return 0, err return 0, err
} }
if txHeight <= 0 { if txHeight <= 0 {
fmt.Printf("txHeight should be grate to 0") //fmt.Printf("txHeight should be grate to 0")
return 0, errors.New("txHeight should be grate to 0") return 0, errors.New("txHeight should be grate to 0")
} }
if txHeight+types.TxHeightFlag < txHeight {
return 0, errors.New("txHeight overflow")
}
return txHeight + types.TxHeightFlag, nil return txHeight + types.TxHeightFlag, nil
} }
...@@ -538,8 +540,12 @@ func (wallet *Wallet) ProcSendToAddress(SendToAddress *types.ReqWalletSendToAddr ...@@ -538,8 +540,12 @@ func (wallet *Wallet) ProcSendToAddress(SendToAddress *types.ReqWalletSendToAddr
} }
Balance := accounts[0].Balance Balance := accounts[0].Balance
amount := SendToAddress.GetAmount() amount := SendToAddress.GetAmount()
//amount必须大于等于0
if amount < 0 {
return nil, types.ErrAmount
}
if !SendToAddress.IsToken { if !SendToAddress.IsToken {
if Balance < amount+wallet.FeeAmount { if Balance-amount < wallet.FeeAmount {
return nil, types.ErrInsufficientBalance return nil, types.ErrInsufficientBalance
} }
} else { } else {
...@@ -547,7 +553,6 @@ func (wallet *Wallet) ProcSendToAddress(SendToAddress *types.ReqWalletSendToAddr ...@@ -547,7 +553,6 @@ func (wallet *Wallet) ProcSendToAddress(SendToAddress *types.ReqWalletSendToAddr
if Balance < wallet.FeeAmount { if Balance < wallet.FeeAmount {
return nil, types.ErrInsufficientBalance return nil, types.ErrInsufficientBalance
} }
if nil == accTokenMap[SendToAddress.TokenSymbol] { if nil == accTokenMap[SendToAddress.TokenSymbol] {
tokenAccDB, err := account.NewAccountDB("token", SendToAddress.TokenSymbol, nil) tokenAccDB, err := account.NewAccountDB("token", SendToAddress.TokenSymbol, nil)
if err != nil { if err != nil {
......
...@@ -479,9 +479,11 @@ func testProcSendToAddress(t *testing.T, wallet *Wallet) { ...@@ -479,9 +479,11 @@ func testProcSendToAddress(t *testing.T, wallet *Wallet) {
msg = wallet.client.NewMessage("wallet", types.EventWalletSendToAddress, withdraw) msg = wallet.client.NewMessage("wallet", types.EventWalletSendToAddress, withdraw)
wallet.client.Send(msg, true) wallet.client.Send(msg, true)
resp, err = wallet.client.Wait(msg) resp, err = wallet.client.Wait(msg)
require.NoError(t, err) //返回ErrAmount错误
replyHash = resp.GetData().(*types.ReplyHash) assert.Equal(t, string(err.Error()), types.ErrAmount.Error())
println("withdraw tx", "ReplyHash", common.ToHex(replyHash.Hash)) require.Error(t, err)
//replyHash = resp.GetData().(*types.ReplyHash)
//println("withdraw tx", "ReplyHash", common.ToHex(replyHash.Hash))
println("TestProcSendToAddress end") println("TestProcSendToAddress end")
println("--------------------------") println("--------------------------")
} }
......
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