Commit 88db31ff authored by vipwzw's avatar vipwzw

update chain33 master

parent cf38751f
......@@ -10,6 +10,8 @@ datadir*
.idea
.vscode
cmd/chain33/chain33
build/cert.pem
build/key.pem
build/chain33*
build/datadir
build/bityuan*
......
......@@ -195,6 +195,16 @@ func (bs *BlockStore) initQuickIndex(height int64) {
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 {
counts := dbm.NewListHelper(bs.db).PrefixCount(seqCBPrefix)
return counts
......@@ -204,6 +214,8 @@ func (bs *BlockStore) addBlockSeqCB(cb *types.BlockSeqCB) error {
if len(cb.Name) > 128 || len(cb.URL) > 1024 {
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))
}
......@@ -461,9 +473,9 @@ func (bs *BlockStore) LoadBlockByHash(hash []byte) (*types.BlockDetail, error) {
return &blockdetail, nil
}
//SaveBlock 批量保存blocks信息到db数据库中
func (bs *BlockStore) SaveBlock(storeBatch dbm.Batch, blockdetail *types.BlockDetail, sequence int64) error {
//SaveBlock 批量保存blocks信息到db数据库中,并返回最新的sequence值
func (bs *BlockStore) SaveBlock(storeBatch dbm.Batch, blockdetail *types.BlockDetail, sequence int64) (int64, error) {
var lastSequence int64 = -1
height := blockdetail.Block.Height
if len(blockdetail.Receipts) == 0 && len(blockdetail.Block.Txs) != 0 {
storeLog.Error("SaveBlock Receipts is nil ", "height", height)
......@@ -478,7 +490,7 @@ func (bs *BlockStore) SaveBlock(storeBatch dbm.Batch, blockdetail *types.BlockDe
body, err := proto.Marshal(&blockbody)
if err != nil {
storeLog.Error("SaveBlock Marshal blockbody", "height", height, "hash", common.ToHex(hash), "error", err)
return err
return lastSequence, err
}
storeBatch.Set(calcHashToBlockBodyKey(hash), body)
......@@ -499,7 +511,7 @@ func (bs *BlockStore) SaveBlock(storeBatch dbm.Batch, blockdetail *types.BlockDe
header, err := proto.Marshal(&blockheader)
if err != nil {
storeLog.Error("SaveBlock Marshal blockheader", "height", height, "hash", common.ToHex(hash), "error", err)
return err
return lastSequence, err
}
storeBatch.Set(calcHashToBlockHeaderKey(hash), header)
......@@ -517,19 +529,19 @@ func (bs *BlockStore) SaveBlock(storeBatch dbm.Batch, blockdetail *types.BlockDe
if isRecordBlockSequence || isParaChain {
//存储记录block序列执行的type add
err = bs.saveBlockSequence(storeBatch, hash, height, AddBlock, sequence)
lastSequence, err = bs.saveBlockSequence(storeBatch, hash, height, AddBlock, sequence)
if err != nil {
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))
return nil
return lastSequence, nil
}
//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
hash := blockdetail.Block.Hash()
......@@ -546,15 +558,15 @@ func (bs *BlockStore) DelBlock(storeBatch dbm.Batch, blockdetail *types.BlockDet
if isRecordBlockSequence || isParaChain {
//存储记录block序列执行的type del
err := bs.saveBlockSequence(storeBatch, hash, height, DelBlock, sequence)
lastSequence, err := bs.saveBlockSequence(storeBatch, hash, height, DelBlock, sequence)
if err != nil {
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))
return nil
return lastSequence, nil
}
//GetTx 通过tx hash 从db数据库中获取tx交易信息
......@@ -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}))
}
//Seq的合法值从0开始的,所以没有获取到或者获取失败都应该返回-1
func (bs *BlockStore) getSeqCBLastNum(name []byte) int64 {
bytes, err := bs.db.Get(caclSeqCBLastNumKey(name))
if bytes == nil || err != nil {
if err != dbm.ErrNotFoundInDb {
return -1
storeLog.Error("getSeqCBLastNum", "error", err)
}
return 0
return -1
}
n, err := decodeHeight(bytes)
if err != nil {
return 0
return -1
}
storeLog.Error("getSeqCBLastNum", "name", string(name), "num", n)
return n
}
//SaveBlockSequence 存储block 序列执行的类型用于blockchain的恢复
//获取当前的序列号,将此序列号加1存储本block的hash ,当主链使能isRecordBlockSequence
// 平行链使能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 newSequence int64
......@@ -921,7 +936,7 @@ func (bs *BlockStore) saveBlockSequence(storeBatch dbm.Batch, hash []byte, heigh
BlockSequenceByte, err := proto.Marshal(&blockSequence)
if err != nil {
storeLog.Error("SaveBlockSequence Marshal BlockSequence", "hash", common.ToHex(hash), "error", err)
return err
return newSequence, err
}
// seq->hash
......@@ -935,7 +950,7 @@ func (bs *BlockStore) saveBlockSequence(storeBatch dbm.Batch, hash []byte, heigh
Sequencebytes := types.Encode(&types.Int64{Data: newSequence})
storeBatch.Set(LastSequence, Sequencebytes)
return nil
return newSequence, nil
}
//LoadBlockBySequence 通过seq高度获取BlockDetail信息
......
......@@ -112,7 +112,7 @@ func TestBlockChain(t *testing.T) {
testRemoveOrphanBlock(t, blockchain)
testLoadBlockBySequence(t, blockchain)
testAddBlockSeqCB(t, blockchain)
testProcDelParaChainBlockMsg(t, mock33, blockchain)
testProcAddParaChainBlockMsg(t, mock33, blockchain)
......@@ -901,3 +901,33 @@ func testProcBlockChainFork(t *testing.T, blockchain *blockchain.BlockChain) {
blockchain.ProcBlockChainFork(curheight-1, curheight+256, "self")
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() {
go chain.processMsg(msg, reqnum, chain.localPrefixCount)
case types.EventAddBlockSeqCB:
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:
go chain.processMsg(msg, reqnum, chain.unknowMsg)
}
......@@ -96,18 +102,36 @@ func (chain *BlockChain) unknowMsg(msg queue.Message) {
}
func (chain *BlockChain) addBlockSeqCB(msg queue.Message) {
if chain.blockStore.seqCBNum() >= MaxSeqCB {
msg.Reply(chain.client.NewMessage("rpc", types.EventAddBlockSeqCB, types.ErrTooManySeqCB))
return
reply := &types.Reply{
IsOk: true,
}
cb := (msg.Data).(*types.BlockSeqCB)
err := chain.blockStore.addBlockSeqCB(cb)
err := chain.ProcAddBlockSeqCB(cb)
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
}
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) {
......
......@@ -274,7 +274,6 @@ func (b *BlockChain) connectBestChain(node *blockNode, block *types.BlockDetail)
//将本block信息存储到数据库中,并更新bestchain的tip节点
func (b *BlockChain) connectBlock(node *blockNode, blockdetail *types.BlockDetail) (*types.BlockDetail, error) {
//blockchain close 时不再处理block
if atomic.LoadInt32(&b.isclosed) == 1 {
return nil, types.ErrIsClosed
......@@ -293,6 +292,8 @@ func (b *BlockChain) connectBlock(node *blockNode, blockdetail *types.BlockDetai
}
var err error
var lastSequence int64
block := blockdetail.Block
prevStateHash := b.bestChain.Tip().statehash
//广播或者同步过来的blcok需要调用执行模块
......@@ -308,27 +309,25 @@ func (b *BlockChain) connectBlock(node *blockNode, blockdetail *types.BlockDetai
}
//要更新node的信息
if node.pid == "self" {
//update node info
prevhash := node.hash
node.statehash = blockdetail.Block.GetStateHash()
node.hash = blockdetail.Block.Hash()
b.index.UpdateNode(prevhash, node)
}
beg := types.Now()
// 写入磁盘
//批量将block信息写入磁盘
beg := types.Now()
// 写入磁盘 批量将block信息写入磁盘
newbatch := b.blockStore.NewBatch(sync)
//保存tx信息到db中 (newbatch, blockdetail)
//保存tx信息到db中
err = b.blockStore.AddTxs(newbatch, blockdetail)
if err != nil {
chainlog.Error("connectBlock indexTxs:", "height", block.Height, "err", err)
return nil, err
}
//chainlog.Debug("connectBlock AddTxs!", "height", block.Height, "batchsync", sync)
//保存block信息到db中
err = b.blockStore.SaveBlock(newbatch, blockdetail, node.sequence)
lastSequence, err = b.blockStore.SaveBlock(newbatch, blockdetail, node.sequence)
if err != nil {
chainlog.Error("connectBlock SaveBlock:", "height", block.Height, "err", err)
return nil, err
......@@ -348,8 +347,6 @@ func (b *BlockChain) connectBlock(node *blockNode, blockdetail *types.BlockDetai
return nil, err
}
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)
......@@ -389,12 +386,16 @@ func (b *BlockChain) connectBlock(node *blockNode, blockdetail *types.BlockDetai
b.SendBlockBroadcast(blockdetail)
}
}
b.pushseq.updateSeq(node.sequence)
//目前非平行链并开启isRecordBlockSequence功能
if isRecordBlockSequence && !isParaChain {
b.pushseq.updateSeq(lastSequence)
}
return blockdetail, nil
}
//从主链中删除blocks
func (b *BlockChain) disconnectBlock(node *blockNode, blockdetail *types.BlockDetail, sequence int64) error {
var lastSequence int64
// 只能从 best chain tip节点开始删除
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))
......@@ -412,7 +413,7 @@ func (b *BlockChain) disconnectBlock(node *blockNode, blockdetail *types.BlockDe
}
//从db中删除block相关的信息
err = b.blockStore.DelBlock(newbatch, blockdetail, sequence)
lastSequence, err = b.blockStore.DelBlock(newbatch, blockdetail, sequence)
if err != nil {
chainlog.Error("disconnectBlock DelBlock:", "height", blockdetail.Block.Height, "err", err)
return err
......@@ -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.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
}
......
......@@ -11,6 +11,7 @@ import (
"github.com/33cn/chain33/types"
)
//pushNotify push Notify
type pushNotify struct {
cb chan *types.BlockSeqCB
seq chan int64
......@@ -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()
if err != nil {
chainlog.Error("listSeqCB", "err", err)
chainlog.Error("LoadBlockLastSequence", "err", err)
return
}
p.updateSeq(last)
notify := p.cmds[name]
notify.seq <- last
}
//每个name 有一个task
......@@ -57,6 +61,7 @@ func (p *pushseq) addTask(cb *types.BlockSeqCB) {
if notify, ok := p.cmds[cb.Name]; ok {
notify.cb <- cb
if cb.URL == "" {
chainlog.Debug("delete callback", "cb", cb)
delete(p.cmds, cb.Name)
}
return
......@@ -67,14 +72,23 @@ func (p *pushseq) addTask(cb *types.BlockSeqCB) {
}
p.cmds[cb.Name].cb <- cb
p.runTask(p.cmds[cb.Name])
//更新最新的seq
p.updateLastSeq()
p.updateLastSeq(cb.Name)
chainlog.Debug("runTask callback", "cb", cb)
}
func (p *pushseq) updateSeq(seq int64) {
p.mu.Lock()
defer p.mu.Unlock()
for _, notify := range p.cmds {
//如果有seq, 那么先读一个出来
select {
case <-notify.seq:
default:
}
//再写入seq(一定不会block,因为加了lock,不存在两个同时写channel的情况)
notify.seq <- seq
}
}
......@@ -127,8 +141,8 @@ func (p *pushseq) runTask(input pushNotify) {
err = p.postData(cb, data)
if err != nil {
chainlog.Error("postdata", "err", err)
//sleep 10s
p.trigeRun(run, 10000*time.Millisecond)
//sleep 60s
p.trigeRun(run, 60000*time.Millisecond)
continue
}
//update seqid
......@@ -141,6 +155,7 @@ func (p *pushseq) runTask(input pushNotify) {
func (p *pushseq) postData(cb *types.BlockSeqCB, data *types.BlockSeq) (err error) {
var postdata []byte
if cb.Encode == "json" {
postdata, err = types.PBToJSON(data)
if err != nil {
......@@ -149,6 +164,7 @@ func (p *pushseq) postData(cb *types.BlockSeqCB, data *types.BlockSeq) (err erro
} else {
postdata = types.Encode(data)
}
//post data in body
var buf bytes.Buffer
g := gzip.NewWriter(&buf)
......@@ -163,6 +179,7 @@ func (p *pushseq) postData(cb *types.BlockSeqCB, data *types.BlockSeq) (err erro
if err != nil {
return err
}
req.Header.Set("Content-Type", "text/plain")
req.Header.Set("Content-Encoding", "gzip")
resp, err := p.client.Do(req)
......@@ -175,8 +192,10 @@ func (p *pushseq) postData(cb *types.BlockSeqCB, data *types.BlockSeq) (err erro
return err
}
if string(body) != "ok" && string(body) != "OK" {
chainlog.Error("postData fail", "cb.name", cb.Name, "body", string(body))
return types.ErrPushSeqPostData
}
chainlog.Debug("postData success", "cb.name", cb.Name, "SeqNum", data.Num)
p.store.setSeqCBLastNum([]byte(cb.Name), data.Num)
return nil
}
......
......@@ -86,3 +86,40 @@ func (chain *BlockChain) ProcGetSeqByHash(hash []byte) (int64, error) {
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
COPY chain33-cli chain33-cli
COPY chain33.toml ./
RUN ./chain33-cli cert --host=127.0.0.1
CMD ["/root/chain33", "-f", "/root/chain33.toml"]
......@@ -11,6 +11,29 @@ type QueueProtocolAPI struct {
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:
func (_m *QueueProtocolAPI) Close() {
_m.Called()
......@@ -453,6 +476,29 @@ func (_m *QueueProtocolAPI) GetSeed(param *types.GetSeedByPw) (*types.ReplySeed,
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
func (_m *QueueProtocolAPI) GetTransactionByAddr(param *types.ReqAddr) (*types.ReplyTxInfos, error) {
ret := _m.Called(param)
......@@ -591,6 +637,29 @@ func (_m *QueueProtocolAPI) IsSync() (*types.Reply, error) {
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
func (_m *QueueProtocolAPI) LocalGet(param *types.LocalDBGet) (*types.LocalReplyValue, error) {
ret := _m.Called(param)
......
......@@ -983,3 +983,45 @@ func (q *QueueProtocol) GetTicketCount() (*types.Int64, error) {
}
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 {
// close chain33
CloseQueue() (*types.Reply, error)
// --------------- 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"
whitelist=["127.0.0.1"]
jrpcFuncWhitelist=["*"]
grpcFuncWhitelist=["*"]
enableTLS=false
certFile="cert.pem"
keyFile="key.pem"
[mempool]
maxTxNumPerAccount=100
......
......@@ -59,6 +59,9 @@ grpcBindAddr="localhost:8802"
whitelist=["127.0.0.1"]
jrpcFuncWhitelist=["*"]
grpcFuncWhitelist=["*"]
enableTLS=false
certFile="cert.pem"
keyFile="key.pem"
[mempool]
poolCacheSize=10240
......
......@@ -59,6 +59,9 @@ grpcBindAddr="localhost:8802"
whitelist=["127.0.0.1"]
jrpcFuncWhitelist=["*"]
grpcFuncWhitelist=["*"]
enableTLS=true
certFile="cert.pem"
keyFile="key.pem"
[mempool]
poolCacheSize=10240
......
......@@ -11,6 +11,7 @@ import (
"testing"
"github.com/33cn/chain33/common/address"
"github.com/33cn/chain33/common/merkle"
_ "github.com/33cn/chain33/system"
"github.com/33cn/chain33/types"
"github.com/33cn/chain33/util"
......@@ -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) {
mock33 := newMockNode()
defer mock33.Close()
......
......@@ -47,6 +47,11 @@ func (g *Grpc) CreateTransaction(ctx context.Context, in *pb.CreateTxIn) (*pb.Un
if err != nil {
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)
if err != nil {
return nil, err
......
......@@ -80,7 +80,10 @@ func (j *JSONRPCServer) Listen() (int, error) {
if err != nil {
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)
}
if err != nil {
writeError(w, r, 0, fmt.Sprintf(`parse request err %s`, err.Error()))
return
......@@ -88,7 +91,7 @@ func (j *JSONRPCServer) Listen() (int, error) {
//Release local request
ipaddr := net.ParseIP(ip)
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) {
writeError(w, r, client.ID, fmt.Sprintf(`The %s method is not authorized!`, funcName))
return
......@@ -109,7 +112,11 @@ func (j *JSONRPCServer) Listen() (int, error) {
})
handler = co.Handler(handler)
if !rpcCfg.EnableTLS {
go http.Serve(listener, handler)
} else {
go http.ServeTLS(listener, handler, rpcCfg.CertFile, rpcCfg.KeyFile)
}
return listener.Addr().(*net.TCPAddr).Port, nil
}
......
......@@ -165,43 +165,8 @@ func (c *Chain33) GetBlocks(in rpctypes.BlockParam, result *interface{}) error {
{
var blockDetails rpctypes.BlockDetails
items := reply.GetItems()
for _, item := range items {
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 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)
if err := convertBlockDetails(items, &blockDetails, in.Isdetail); err != nil {
return err
}
*result = &blockDetails
}
......@@ -1139,7 +1104,14 @@ func (c *Chain33) GetBlockByHashes(in rpctypes.ReqHashes, result *interface{}) e
if err != nil {
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
}
......@@ -1148,16 +1120,11 @@ func (c *Chain33) CreateTransaction(in *rpctypes.CreateTxIn, result *interface{}
if in == nil {
return types.ErrInvalidParam
}
exec := types.LoadExecutorType(in.Execer)
if exec == nil {
return types.ErrExecNameNotAllow
}
tx, err := exec.CreateTx(in.ActionName, in.Payload)
btx, err := types.CallCreateTxJSON(in.Execer, in.ActionName, in.Payload)
if err != nil {
log.Error("CreateTransaction", "err", err.Error())
return err
}
*result = hex.EncodeToString(types.Encode(tx))
*result = hex.EncodeToString(btx)
return nil
}
......@@ -1177,3 +1144,80 @@ func (c *Chain33) GetExecBalance(in *types.ReqGetExecBalance, result *interface{
*result = hex.EncodeToString(types.Encode(resp))
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) {
in := &rpctypes.CreateTxIn{Execer: "notExist", ActionName: "x", Payload: []byte("x")}
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")}
err = client.CreateTransaction(in, &result)
......
......@@ -7,6 +7,7 @@ package jsonclient
import (
"bytes"
"crypto/tls"
"encoding/json"
"fmt"
"io/ioutil"
......@@ -21,6 +22,8 @@ import (
type JSONClient struct {
url string
prefix string
tlsVerify bool
client *http.Client
}
func addPrefix(prefix, name string) string {
......@@ -32,12 +35,21 @@ func addPrefix(prefix, name string) string {
// NewJSONClient produce a json object
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
func New(prefix, url string) (*JSONClient, error) {
return &JSONClient{url: url, prefix: prefix}, nil
func New(prefix, url string, tlsVerify bool) (*JSONClient, error) {
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 {
......@@ -63,7 +75,7 @@ func (client *JSONClient) Call(method string, params, resp interface{}) error {
return err
}
//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 {
return err
}
......
......@@ -14,8 +14,8 @@ import (
"github.com/33cn/chain33/queue"
"github.com/33cn/chain33/types"
"golang.org/x/net/context"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials"
_ "google.golang.org/grpc/encoding/gzip" // register gzip
)
......@@ -26,6 +26,7 @@ var (
grpcFuncWhitelist = make(map[string]bool)
jrpcFuncBlacklist = make(map[string]bool)
grpcFuncBlacklist = make(map[string]bool)
rpcFilterPrintFuncBlacklist = make(map[string]bool)
)
// Chain33 a channel client
......@@ -149,6 +150,14 @@ func NewGRpcServer(c queue.Client, api client.QueueProtocolAPI) *Grpcserver {
return handler(ctx, req)
}
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...)
s.s = server
types.RegisterChain33Server(server, s.grpc)
......@@ -182,6 +191,7 @@ func InitCfg(cfg *types.RPC) {
InitGrpcFuncWhitelist(cfg)
InitJrpcFuncBlacklist(cfg)
InitGrpcFuncBlacklist(cfg)
InitFilterPrintFuncBlacklist()
}
// New produce a rpc by cfg
......@@ -346,3 +356,19 @@ func InitGrpcFuncBlacklist(cfg *types.RPC) {
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) {
GroupCount: tx.GroupCount,
Header: common.ToHex(tx.Header),
Next: common.ToHex(tx.Next),
Hash: common.ToHex(tx.Hash()),
}
if result.Amount != 0 {
result.AmountFmt = strconv.FormatFloat(float64(result.Amount)/float64(types.Coin), 'f', 4, 64)
......
......@@ -83,6 +83,7 @@ type Transaction struct {
GroupCount int32 `json:"groupCount,omitempty"`
Header string `json:"header,omitempty"`
Next string `json:"next,omitempty"`
Hash string `json:"hash,omitempty"`
}
// ReceiptLog defines receipt log command
......
......@@ -47,6 +47,12 @@ func New(cfg *types.Consensus, sub []byte) queue.Module {
if subcfg.WaitTxMs == 0 {
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}
c.SetChild(solo)
return solo
......
......@@ -35,6 +35,9 @@ func BlockCmd() *cobra.Command {
GetBlockByHashsCmd(),
GetBlockSequencesCmd(),
GetLastBlockSequenceCmd(),
AddBlockSeqCallBackCmd(),
ListBlockSeqCallBackCmd(),
GetSeqCallBackLastNumCmd(),
)
return cmd
......@@ -295,3 +298,89 @@ func getblockbyhashs(cmd *cobra.Command, args []string) {
//ctx.SetResultCb(parseQueryTxsByHashesRes)
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 {
GroupCount int32 `json:"groupCount,omitempty"`
Header string `json:"header,omitempty"`
Next string `json:"next,omitempty"`
Hash string `json:"hash,omitempty"`
}
// ReceiptAccountTransfer defines receipt account transfer
......
......@@ -39,6 +39,7 @@ func DecodeTransaction(tx *rpctypes.Transaction) *TxResult {
GroupCount: tx.GroupCount,
Header: tx.Header,
Next: tx.Next,
Hash: tx.Hash,
}
return result
}
......
......@@ -353,7 +353,7 @@ func parseTxHeight(expire string) error {
return err
}
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")
}
......
......@@ -6,7 +6,6 @@
package types
import (
"encoding/json"
"reflect"
"github.com/33cn/chain33/common/address"
......@@ -60,13 +59,6 @@ func (m ManageType) Amount(tx *types.Transaction) (int64, error) {
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
func (m *ManageType) GetLogMap() map[int64]*types.LogInfo {
return logmap
......@@ -86,3 +78,8 @@ func (m ManageType) GetRealToAddr(tx *types.Transaction) string {
func (m ManageType) GetTypeMap() map[string]int32 {
return actionName
}
// GetName reset name
func (m *ManageType) GetName() string {
return ManageX
}
......@@ -340,6 +340,45 @@ func (m *BlockSeqCB) GetEncode() string {
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 {
Num int64 `protobuf:"varint,1,opt,name=num,proto3" json:"num,omitempty"`
Seq *BlockSequence `protobuf:"bytes,2,opt,name=seq,proto3" json:"seq,omitempty"`
......@@ -353,7 +392,7 @@ func (m *BlockSeq) Reset() { *m = BlockSeq{} }
func (m *BlockSeq) String() string { return proto.CompactTextString(m) }
func (*BlockSeq) ProtoMessage() {}
func (*BlockSeq) Descriptor() ([]byte, []int) {
return fileDescriptor_e9ac6287ce250c9a, []int{4}
return fileDescriptor_e9ac6287ce250c9a, []int{5}
}
func (m *BlockSeq) XXX_Unmarshal(b []byte) error {
......@@ -408,7 +447,7 @@ func (m *BlockPid) Reset() { *m = BlockPid{} }
func (m *BlockPid) String() string { return proto.CompactTextString(m) }
func (*BlockPid) ProtoMessage() {}
func (*BlockPid) Descriptor() ([]byte, []int) {
return fileDescriptor_e9ac6287ce250c9a, []int{5}
return fileDescriptor_e9ac6287ce250c9a, []int{6}
}
func (m *BlockPid) XXX_Unmarshal(b []byte) error {
......@@ -455,7 +494,7 @@ func (m *BlockDetails) Reset() { *m = BlockDetails{} }
func (m *BlockDetails) String() string { return proto.CompactTextString(m) }
func (*BlockDetails) ProtoMessage() {}
func (*BlockDetails) Descriptor() ([]byte, []int) {
return fileDescriptor_e9ac6287ce250c9a, []int{6}
return fileDescriptor_e9ac6287ce250c9a, []int{7}
}
func (m *BlockDetails) XXX_Unmarshal(b []byte) error {
......@@ -495,7 +534,7 @@ func (m *Headers) Reset() { *m = Headers{} }
func (m *Headers) String() string { return proto.CompactTextString(m) }
func (*Headers) ProtoMessage() {}
func (*Headers) Descriptor() ([]byte, []int) {
return fileDescriptor_e9ac6287ce250c9a, []int{7}
return fileDescriptor_e9ac6287ce250c9a, []int{8}
}
func (m *Headers) XXX_Unmarshal(b []byte) error {
......@@ -535,7 +574,7 @@ func (m *HeadersPid) Reset() { *m = HeadersPid{} }
func (m *HeadersPid) String() string { return proto.CompactTextString(m) }
func (*HeadersPid) ProtoMessage() {}
func (*HeadersPid) Descriptor() ([]byte, []int) {
return fileDescriptor_e9ac6287ce250c9a, []int{8}
return fileDescriptor_e9ac6287ce250c9a, []int{9}
}
func (m *HeadersPid) XXX_Unmarshal(b []byte) error {
......@@ -587,7 +626,7 @@ func (m *BlockOverview) Reset() { *m = BlockOverview{} }
func (m *BlockOverview) String() string { return proto.CompactTextString(m) }
func (*BlockOverview) ProtoMessage() {}
func (*BlockOverview) Descriptor() ([]byte, []int) {
return fileDescriptor_e9ac6287ce250c9a, []int{9}
return fileDescriptor_e9ac6287ce250c9a, []int{10}
}
func (m *BlockOverview) XXX_Unmarshal(b []byte) error {
......@@ -646,7 +685,7 @@ func (m *BlockDetail) Reset() { *m = BlockDetail{} }
func (m *BlockDetail) String() string { return proto.CompactTextString(m) }
func (*BlockDetail) ProtoMessage() {}
func (*BlockDetail) Descriptor() ([]byte, []int) {
return fileDescriptor_e9ac6287ce250c9a, []int{10}
return fileDescriptor_e9ac6287ce250c9a, []int{11}
}
func (m *BlockDetail) XXX_Unmarshal(b []byte) error {
......@@ -706,7 +745,7 @@ func (m *Receipts) Reset() { *m = Receipts{} }
func (m *Receipts) String() string { return proto.CompactTextString(m) }
func (*Receipts) ProtoMessage() {}
func (*Receipts) Descriptor() ([]byte, []int) {
return fileDescriptor_e9ac6287ce250c9a, []int{11}
return fileDescriptor_e9ac6287ce250c9a, []int{12}
}
func (m *Receipts) XXX_Unmarshal(b []byte) error {
......@@ -745,7 +784,7 @@ func (m *PrivacyKV) Reset() { *m = PrivacyKV{} }
func (m *PrivacyKV) String() string { return proto.CompactTextString(m) }
func (*PrivacyKV) ProtoMessage() {}
func (*PrivacyKV) Descriptor() ([]byte, []int) {
return fileDescriptor_e9ac6287ce250c9a, []int{12}
return fileDescriptor_e9ac6287ce250c9a, []int{13}
}
func (m *PrivacyKV) XXX_Unmarshal(b []byte) error {
......@@ -787,7 +826,7 @@ func (m *PrivacyKVToken) Reset() { *m = PrivacyKVToken{} }
func (m *PrivacyKVToken) String() string { return proto.CompactTextString(m) }
func (*PrivacyKVToken) ProtoMessage() {}
func (*PrivacyKVToken) Descriptor() ([]byte, []int) {
return fileDescriptor_e9ac6287ce250c9a, []int{13}
return fileDescriptor_e9ac6287ce250c9a, []int{14}
}
func (m *PrivacyKVToken) XXX_Unmarshal(b []byte) error {
......@@ -848,7 +887,7 @@ func (m *ReceiptsAndPrivacyKV) Reset() { *m = ReceiptsAndPrivacyKV{} }
func (m *ReceiptsAndPrivacyKV) String() string { return proto.CompactTextString(m) }
func (*ReceiptsAndPrivacyKV) ProtoMessage() {}
func (*ReceiptsAndPrivacyKV) Descriptor() ([]byte, []int) {
return fileDescriptor_e9ac6287ce250c9a, []int{14}
return fileDescriptor_e9ac6287ce250c9a, []int{15}
}
func (m *ReceiptsAndPrivacyKV) XXX_Unmarshal(b []byte) error {
......@@ -894,7 +933,7 @@ func (m *ReceiptCheckTxList) Reset() { *m = ReceiptCheckTxList{} }
func (m *ReceiptCheckTxList) String() string { return proto.CompactTextString(m) }
func (*ReceiptCheckTxList) ProtoMessage() {}
func (*ReceiptCheckTxList) Descriptor() ([]byte, []int) {
return fileDescriptor_e9ac6287ce250c9a, []int{15}
return fileDescriptor_e9ac6287ce250c9a, []int{16}
}
func (m *ReceiptCheckTxList) XXX_Unmarshal(b []byte) error {
......@@ -939,7 +978,7 @@ func (m *ChainStatus) Reset() { *m = ChainStatus{} }
func (m *ChainStatus) String() string { return proto.CompactTextString(m) }
func (*ChainStatus) ProtoMessage() {}
func (*ChainStatus) Descriptor() ([]byte, []int) {
return fileDescriptor_e9ac6287ce250c9a, []int{16}
return fileDescriptor_e9ac6287ce250c9a, []int{17}
}
func (m *ChainStatus) XXX_Unmarshal(b []byte) error {
......@@ -1000,7 +1039,7 @@ func (m *ReqBlocks) Reset() { *m = ReqBlocks{} }
func (m *ReqBlocks) String() string { return proto.CompactTextString(m) }
func (*ReqBlocks) ProtoMessage() {}
func (*ReqBlocks) Descriptor() ([]byte, []int) {
return fileDescriptor_e9ac6287ce250c9a, []int{17}
return fileDescriptor_e9ac6287ce250c9a, []int{18}
}
func (m *ReqBlocks) XXX_Unmarshal(b []byte) error {
......@@ -1060,7 +1099,7 @@ func (m *MempoolSize) Reset() { *m = MempoolSize{} }
func (m *MempoolSize) String() string { return proto.CompactTextString(m) }
func (*MempoolSize) ProtoMessage() {}
func (*MempoolSize) Descriptor() ([]byte, []int) {
return fileDescriptor_e9ac6287ce250c9a, []int{18}
return fileDescriptor_e9ac6287ce250c9a, []int{19}
}
func (m *MempoolSize) XXX_Unmarshal(b []byte) error {
......@@ -1099,7 +1138,7 @@ func (m *ReplyBlockHeight) Reset() { *m = ReplyBlockHeight{} }
func (m *ReplyBlockHeight) String() string { return proto.CompactTextString(m) }
func (*ReplyBlockHeight) ProtoMessage() {}
func (*ReplyBlockHeight) Descriptor() ([]byte, []int) {
return fileDescriptor_e9ac6287ce250c9a, []int{19}
return fileDescriptor_e9ac6287ce250c9a, []int{20}
}
func (m *ReplyBlockHeight) XXX_Unmarshal(b []byte) error {
......@@ -1142,7 +1181,7 @@ func (m *BlockBody) Reset() { *m = BlockBody{} }
func (m *BlockBody) String() string { return proto.CompactTextString(m) }
func (*BlockBody) ProtoMessage() {}
func (*BlockBody) Descriptor() ([]byte, []int) {
return fileDescriptor_e9ac6287ce250c9a, []int{20}
return fileDescriptor_e9ac6287ce250c9a, []int{21}
}
func (m *BlockBody) XXX_Unmarshal(b []byte) error {
......@@ -1189,7 +1228,7 @@ func (m *IsCaughtUp) Reset() { *m = IsCaughtUp{} }
func (m *IsCaughtUp) String() string { return proto.CompactTextString(m) }
func (*IsCaughtUp) ProtoMessage() {}
func (*IsCaughtUp) Descriptor() ([]byte, []int) {
return fileDescriptor_e9ac6287ce250c9a, []int{21}
return fileDescriptor_e9ac6287ce250c9a, []int{22}
}
func (m *IsCaughtUp) XXX_Unmarshal(b []byte) error {
......@@ -1229,7 +1268,7 @@ func (m *IsNtpClockSync) Reset() { *m = IsNtpClockSync{} }
func (m *IsNtpClockSync) String() string { return proto.CompactTextString(m) }
func (*IsNtpClockSync) ProtoMessage() {}
func (*IsNtpClockSync) Descriptor() ([]byte, []int) {
return fileDescriptor_e9ac6287ce250c9a, []int{22}
return fileDescriptor_e9ac6287ce250c9a, []int{23}
}
func (m *IsNtpClockSync) XXX_Unmarshal(b []byte) error {
......@@ -1273,7 +1312,7 @@ func (m *ChainExecutor) Reset() { *m = ChainExecutor{} }
func (m *ChainExecutor) String() string { return proto.CompactTextString(m) }
func (*ChainExecutor) ProtoMessage() {}
func (*ChainExecutor) Descriptor() ([]byte, []int) {
return fileDescriptor_e9ac6287ce250c9a, []int{23}
return fileDescriptor_e9ac6287ce250c9a, []int{24}
}
func (m *ChainExecutor) XXX_Unmarshal(b []byte) error {
......@@ -1342,7 +1381,7 @@ func (m *BlockSequence) Reset() { *m = BlockSequence{} }
func (m *BlockSequence) String() string { return proto.CompactTextString(m) }
func (*BlockSequence) ProtoMessage() {}
func (*BlockSequence) Descriptor() ([]byte, []int) {
return fileDescriptor_e9ac6287ce250c9a, []int{24}
return fileDescriptor_e9ac6287ce250c9a, []int{25}
}
func (m *BlockSequence) XXX_Unmarshal(b []byte) error {
......@@ -1389,7 +1428,7 @@ func (m *BlockSequences) Reset() { *m = BlockSequences{} }
func (m *BlockSequences) String() string { return proto.CompactTextString(m) }
func (*BlockSequences) ProtoMessage() {}
func (*BlockSequences) Descriptor() ([]byte, []int) {
return fileDescriptor_e9ac6287ce250c9a, []int{25}
return fileDescriptor_e9ac6287ce250c9a, []int{26}
}
func (m *BlockSequences) XXX_Unmarshal(b []byte) error {
......@@ -1432,7 +1471,7 @@ func (m *ParaChainBlockDetail) Reset() { *m = ParaChainBlockDetail{} }
func (m *ParaChainBlockDetail) String() string { return proto.CompactTextString(m) }
func (*ParaChainBlockDetail) ProtoMessage() {}
func (*ParaChainBlockDetail) Descriptor() ([]byte, []int) {
return fileDescriptor_e9ac6287ce250c9a, []int{26}
return fileDescriptor_e9ac6287ce250c9a, []int{27}
}
func (m *ParaChainBlockDetail) XXX_Unmarshal(b []byte) error {
......@@ -1472,6 +1511,7 @@ func init() {
proto.RegisterType((*Block)(nil), "types.Block")
proto.RegisterType((*Blocks)(nil), "types.Blocks")
proto.RegisterType((*BlockSeqCB)(nil), "types.BlockSeqCB")
proto.RegisterType((*BlockSeqCBs)(nil), "types.BlockSeqCBs")
proto.RegisterType((*BlockSeq)(nil), "types.BlockSeq")
proto.RegisterType((*BlockPid)(nil), "types.BlockPid")
proto.RegisterType((*BlockDetails)(nil), "types.BlockDetails")
......@@ -1500,73 +1540,74 @@ func init() {
func init() { proto.RegisterFile("blockchain.proto", fileDescriptor_e9ac6287ce250c9a) }
var fileDescriptor_e9ac6287ce250c9a = []byte{
// 1085 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x56, 0xdf, 0x6f, 0xe3, 0xc4,
0x13, 0x97, 0xf3, 0xab, 0xc9, 0x24, 0xcd, 0xb7, 0xdf, 0x55, 0x40, 0xd6, 0x09, 0xb8, 0xdc, 0x72,
0x3a, 0x45, 0xc7, 0x29, 0x95, 0x5a, 0x04, 0xf7, 0x00, 0x12, 0x34, 0x45, 0x6a, 0xaf, 0xc7, 0x51,
0xb6, 0xbd, 0x3e, 0xf0, 0xb6, 0xb5, 0xb7, 0xb5, 0xd5, 0xf8, 0x47, 0xbd, 0xeb, 0x10, 0xf3, 0x3f,
0xf0, 0x57, 0xf0, 0x86, 0xf8, 0x23, 0xd1, 0xce, 0xae, 0x63, 0x3b, 0xb4, 0x48, 0x48, 0xbc, 0xf0,
0xb6, 0xf3, 0x7b, 0xe6, 0x33, 0x9e, 0x19, 0xc3, 0xde, 0xf5, 0x32, 0xf1, 0xee, 0xbc, 0x80, 0x87,
0xf1, 0x3c, 0xcd, 0x12, 0x95, 0x90, 0xae, 0x2a, 0x52, 0x21, 0x9f, 0xfc, 0x5f, 0x65, 0x3c, 0x96,
0xdc, 0x53, 0x61, 0x62, 0x25, 0x4f, 0x46, 0x5e, 0x12, 0x45, 0x25, 0x45, 0xff, 0x68, 0x41, 0xef,
0x44, 0x70, 0x5f, 0x64, 0xc4, 0x85, 0x9d, 0x95, 0xc8, 0x64, 0x98, 0xc4, 0xae, 0x33, 0x75, 0x66,
0x6d, 0x56, 0x92, 0xe4, 0x13, 0x80, 0x94, 0x67, 0x22, 0x56, 0x27, 0x5c, 0x06, 0x6e, 0x6b, 0xea,
0xcc, 0x46, 0xac, 0xc6, 0x21, 0x1f, 0x42, 0x4f, 0xad, 0x51, 0xd6, 0x46, 0x99, 0xa5, 0xc8, 0x47,
0x30, 0x90, 0x8a, 0x2b, 0x81, 0xa2, 0x0e, 0x8a, 0x2a, 0x86, 0xb6, 0x0a, 0x44, 0x78, 0x1b, 0x28,
0xb7, 0x8b, 0xe1, 0x2c, 0xa5, 0xad, 0xb0, 0x9c, 0xcb, 0x30, 0x12, 0x6e, 0x0f, 0x45, 0x15, 0x43,
0x67, 0xa9, 0xd6, 0x8b, 0x24, 0x8f, 0x95, 0x3b, 0x30, 0x59, 0x5a, 0x92, 0x10, 0xe8, 0x04, 0x3a,
0x10, 0x60, 0x20, 0x7c, 0xeb, 0xcc, 0xfd, 0xf0, 0xe6, 0x26, 0xf4, 0xf2, 0xa5, 0x2a, 0xdc, 0xe1,
0xd4, 0x99, 0xed, 0xb2, 0x1a, 0x87, 0xcc, 0x61, 0x20, 0xc3, 0xdb, 0x98, 0xab, 0x3c, 0x13, 0x6e,
0x7f, 0xea, 0xcc, 0x86, 0x07, 0x7b, 0x73, 0x84, 0x6e, 0x7e, 0x51, 0xf2, 0x59, 0xa5, 0x42, 0x7f,
0x6b, 0x41, 0xf7, 0x48, 0xe7, 0xf2, 0x1f, 0x41, 0xeb, 0x5f, 0xae, 0x9f, 0x3c, 0x87, 0xb6, 0x5a,
0x4b, 0x77, 0x67, 0xda, 0x9e, 0x0d, 0x0f, 0x88, 0xd5, 0xbc, 0xac, 0xbe, 0x31, 0xa6, 0xc5, 0xf4,
0x15, 0xf4, 0x10, 0x24, 0x49, 0x28, 0x74, 0x43, 0x25, 0x22, 0xe9, 0x3a, 0x68, 0x31, 0xb2, 0x16,
0x28, 0x65, 0x46, 0x44, 0xdf, 0x00, 0x20, 0x7d, 0x21, 0xee, 0x17, 0x47, 0xba, 0x8b, 0x31, 0x8f,
0x04, 0x82, 0x3a, 0x60, 0xf8, 0x26, 0x7b, 0xd0, 0x7e, 0xcf, 0xde, 0x22, 0x94, 0x03, 0xa6, 0x9f,
0x1a, 0x0d, 0x11, 0x7b, 0x89, 0x2f, 0x10, 0xc3, 0x01, 0xb3, 0x14, 0x4d, 0xa1, 0x5f, 0xfa, 0xd2,
0x56, 0x71, 0x1e, 0xd9, 0xee, 0xe8, 0x27, 0x79, 0x01, 0x6d, 0x29, 0xee, 0xd1, 0xcf, 0xf0, 0x60,
0x52, 0xcf, 0xe5, 0x42, 0xdc, 0xe7, 0x22, 0xf6, 0x04, 0xd3, 0x0a, 0xe4, 0x25, 0xf4, 0x7c, 0xa1,
0x78, 0xb8, 0x44, 0xef, 0x55, 0xa1, 0xa8, 0x7a, 0x8c, 0x12, 0x66, 0x35, 0xe8, 0x37, 0x36, 0xe2,
0x79, 0xe8, 0xeb, 0x88, 0x69, 0xe8, 0xdb, 0xd4, 0xf5, 0x53, 0xd7, 0x8f, 0xcd, 0xb0, 0x31, 0xb7,
0xea, 0x47, 0x11, 0x7d, 0x0d, 0xa3, 0x9a, 0x63, 0x49, 0x66, 0x4d, 0xcc, 0x1e, 0x0a, 0x6e, 0x91,
0x9b, 0xc3, 0x8e, 0x99, 0x5d, 0x49, 0x3e, 0x6d, 0x1a, 0xed, 0x5a, 0x23, 0x23, 0x2e, 0xf5, 0x4f,
0x00, 0xac, 0xfe, 0xc3, 0xd9, 0xce, 0x60, 0x27, 0x30, 0x72, 0x9b, 0xef, 0xb8, 0xe1, 0x46, 0xb2,
0x52, 0x4c, 0x03, 0xd8, 0xc5, 0x7c, 0x7e, 0x58, 0x89, 0x6c, 0x15, 0x8a, 0x9f, 0xc9, 0x33, 0xe8,
0x68, 0x19, 0x7a, 0xfb, 0x4b, 0x78, 0x14, 0xd5, 0x27, 0xb7, 0xd5, 0x9c, 0xdc, 0x27, 0xd0, 0x37,
0x33, 0x20, 0xa4, 0xdb, 0x9e, 0xb6, 0x67, 0x23, 0xb6, 0xa1, 0xe9, 0xef, 0x0e, 0x0c, 0x6b, 0xa5,
0x57, 0x88, 0x3a, 0x8f, 0x22, 0x4a, 0xe6, 0xd0, 0xcf, 0x84, 0x27, 0xc2, 0x54, 0xe9, 0x42, 0xea,
0x20, 0x32, 0xc3, 0x3e, 0xe6, 0x8a, 0xb3, 0x8d, 0x0e, 0x79, 0x0a, 0xad, 0xb3, 0x2b, 0x8c, 0x3c,
0x3c, 0xf8, 0x9f, 0xd5, 0x3c, 0x13, 0xc5, 0x15, 0x5f, 0xe6, 0x82, 0xb5, 0xce, 0xae, 0xc8, 0x0b,
0x18, 0xa7, 0x99, 0x58, 0x5d, 0x28, 0xae, 0x72, 0x59, 0x9b, 0xcf, 0x2d, 0x2e, 0xfd, 0x02, 0xfa,
0xac, 0x74, 0xfa, 0xb2, 0x96, 0x84, 0x69, 0xca, 0xb8, 0x99, 0x44, 0x95, 0x00, 0x7d, 0x03, 0x83,
0xf3, 0x2c, 0x5c, 0x71, 0xaf, 0x38, 0xbb, 0x22, 0x5f, 0xeb, 0x60, 0x96, 0xb8, 0x4c, 0xee, 0x44,
0x6c, 0xcd, 0x3f, 0xb0, 0xe6, 0xe7, 0x0d, 0x21, 0xdb, 0x52, 0xa6, 0x05, 0x8c, 0x9b, 0x1a, 0x64,
0x02, 0x5d, 0x65, 0xfd, 0xe8, 0x56, 0x1b, 0xc2, 0xb4, 0xe3, 0x34, 0xf6, 0xc5, 0x1a, 0xdb, 0xd1,
0x65, 0x25, 0x69, 0x16, 0x54, 0xd0, 0x58, 0x50, 0xb8, 0x4c, 0x0d, 0x4c, 0x9d, 0x47, 0x61, 0xa2,
0x12, 0x26, 0x65, 0xf9, 0xdf, 0xc6, 0x7e, 0x55, 0xd1, 0x67, 0x0d, 0x28, 0x9c, 0x9a, 0x79, 0xa9,
0x5e, 0x6b, 0xc6, 0x1c, 0x06, 0x9b, 0x8a, 0xec, 0x67, 0xb8, 0xb7, 0x5d, 0x39, 0xab, 0x54, 0xe8,
0x0c, 0x88, 0xf5, 0xb2, 0x08, 0x84, 0x77, 0x77, 0xb9, 0x7e, 0x1b, 0x4a, 0x3c, 0x06, 0x22, 0xcb,
0x0c, 0xf2, 0x03, 0x86, 0x6f, 0x5a, 0xc0, 0x70, 0xa1, 0x4f, 0xa4, 0x69, 0x18, 0x79, 0x0e, 0xbb,
0x5e, 0x9e, 0xe1, 0x5a, 0x36, 0x8b, 0xd5, 0x6c, 0x8a, 0x26, 0x93, 0x4c, 0x61, 0x18, 0x89, 0x28,
0x4d, 0x92, 0xe5, 0x45, 0xf8, 0x8b, 0xb0, 0x5f, 0x6e, 0x9d, 0x45, 0x28, 0x8c, 0x22, 0x79, 0xfb,
0x63, 0x2e, 0x72, 0x81, 0x2a, 0x6d, 0x54, 0x69, 0xf0, 0x28, 0x87, 0x01, 0x13, 0xf7, 0x76, 0x29,
0x4e, 0xa0, 0x2b, 0x15, 0xcf, 0xca, 0x80, 0x86, 0xd0, 0xe3, 0x28, 0x62, 0xdf, 0x06, 0xd0, 0x4f,
0x3d, 0x16, 0xa1, 0x3c, 0xae, 0x16, 0x51, 0x9f, 0x6d, 0xe8, 0x72, 0x78, 0x3b, 0x58, 0x9e, 0x7e,
0xd2, 0x67, 0x30, 0xfc, 0xbe, 0x96, 0x15, 0x81, 0x8e, 0xd4, 0xd9, 0x98, 0x18, 0xf8, 0xa6, 0x2f,
0x61, 0x8f, 0x89, 0x74, 0x59, 0x60, 0x1e, 0xb6, 0xbe, 0xea, 0xae, 0x38, 0xf5, 0xbb, 0xa2, 0x33,
0x46, 0xb5, 0xa3, 0xc4, 0x2f, 0xca, 0xb5, 0xef, 0xfc, 0xed, 0xda, 0xff, 0xa7, 0x63, 0x47, 0x5f,
0x01, 0x9c, 0xca, 0x05, 0xcf, 0x6f, 0x03, 0xf5, 0x3e, 0xd5, 0xa7, 0xea, 0x54, 0x7a, 0x48, 0xe5,
0x29, 0x26, 0xd3, 0x67, 0x35, 0x0e, 0x7d, 0x0d, 0xe3, 0x53, 0xf9, 0x4e, 0xa5, 0x0b, 0xdc, 0xd7,
0x45, 0xec, 0xe9, 0xa9, 0x0c, 0x65, 0xac, 0x52, 0x0f, 0x61, 0x2d, 0x62, 0xcf, 0x5a, 0x6d, 0x71,
0xe9, 0xaf, 0x0e, 0xec, 0x62, 0xe3, 0xbf, 0x5b, 0x0b, 0x2f, 0x57, 0x49, 0xa6, 0x8b, 0xf6, 0xb3,
0x70, 0x25, 0x32, 0x3b, 0x12, 0x96, 0xd2, 0x88, 0xdf, 0xe4, 0xb1, 0xf7, 0x4e, 0x1f, 0x20, 0x73,
0x6d, 0x36, 0x74, 0xf3, 0x3c, 0xb7, 0xb7, 0xcf, 0xf3, 0x04, 0xba, 0x29, 0xcf, 0x78, 0x64, 0x17,
0x83, 0x21, 0x34, 0x57, 0xac, 0x55, 0xc6, 0xf1, 0x66, 0x8f, 0x98, 0x21, 0xe8, 0x97, 0x76, 0x79,
0x96, 0x47, 0x47, 0xf7, 0x0a, 0xbd, 0x3a, 0xe6, 0xcf, 0x05, 0x1d, 0x12, 0xe8, 0x5c, 0x16, 0x69,
0xf9, 0xc1, 0xe1, 0x9b, 0x7e, 0x05, 0xe3, 0x86, 0xa1, 0x5e, 0x32, 0x8d, 0xb5, 0xff, 0xf0, 0x4d,
0xb3, 0xdb, 0x3f, 0x80, 0xc9, 0x39, 0xcf, 0x38, 0x22, 0x51, 0xdf, 0xa8, 0x9f, 0xc3, 0x10, 0xd7,
0xa6, 0x3d, 0x79, 0xce, 0xa3, 0x27, 0xaf, 0xae, 0xa6, 0xa1, 0x92, 0x36, 0x80, 0xcd, 0x71, 0x43,
0x1f, 0x3d, 0xfd, 0xe9, 0xe3, 0xdb, 0x50, 0x05, 0xf9, 0xf5, 0xdc, 0x4b, 0xa2, 0xfd, 0xc3, 0x43,
0x2f, 0xde, 0xc7, 0x7f, 0xd3, 0xc3, 0xc3, 0x7d, 0xf4, 0x7a, 0xdd, 0xc3, 0x9f, 0xcf, 0xc3, 0x3f,
0x03, 0x00, 0x00, 0xff, 0xff, 0x97, 0x32, 0x81, 0xf9, 0xb8, 0x0a, 0x00, 0x00,
// 1097 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x56, 0x5f, 0x6f, 0xe3, 0x44,
0x10, 0x97, 0xf3, 0xaf, 0xc9, 0x24, 0x0d, 0xbd, 0x55, 0x40, 0x51, 0x05, 0x5c, 0x6e, 0x39, 0x1d,
0x51, 0x39, 0xa5, 0x52, 0x8b, 0x8e, 0x7b, 0x00, 0x09, 0x9a, 0x22, 0xb5, 0xd7, 0xe3, 0x28, 0xdb,
0x5e, 0x1f, 0x78, 0xdb, 0xda, 0xdb, 0xda, 0x6a, 0xfc, 0xa7, 0xde, 0x75, 0x88, 0xf9, 0x0e, 0x7c,
0x0a, 0xde, 0x10, 0x1f, 0x12, 0xed, 0xec, 0x3a, 0xb6, 0x43, 0x8b, 0x84, 0xc4, 0x0b, 0x6f, 0x3b,
0xff, 0x67, 0x7e, 0xe3, 0x99, 0x31, 0xec, 0x5c, 0x2f, 0x62, 0xf7, 0xce, 0xf5, 0x79, 0x10, 0xcd,
0x92, 0x34, 0x56, 0x31, 0x69, 0xab, 0x3c, 0x11, 0x72, 0xf7, 0x89, 0x4a, 0x79, 0x24, 0xb9, 0xab,
0x82, 0xd8, 0x4a, 0x76, 0x07, 0x6e, 0x1c, 0x86, 0x05, 0x45, 0xff, 0x6c, 0x40, 0xe7, 0x44, 0x70,
0x4f, 0xa4, 0x64, 0x0c, 0x5b, 0x4b, 0x91, 0xca, 0x20, 0x8e, 0xc6, 0xce, 0xc4, 0x99, 0x36, 0x59,
0x41, 0x92, 0x4f, 0x01, 0x12, 0x9e, 0x8a, 0x48, 0x9d, 0x70, 0xe9, 0x8f, 0x1b, 0x13, 0x67, 0x3a,
0x60, 0x15, 0x0e, 0xf9, 0x08, 0x3a, 0x6a, 0x85, 0xb2, 0x26, 0xca, 0x2c, 0x45, 0x3e, 0x86, 0x9e,
0x54, 0x5c, 0x09, 0x14, 0xb5, 0x50, 0x54, 0x32, 0xb4, 0x95, 0x2f, 0x82, 0x5b, 0x5f, 0x8d, 0xdb,
0x18, 0xce, 0x52, 0xda, 0x0a, 0xcb, 0xb9, 0x0c, 0x42, 0x31, 0xee, 0xa0, 0xa8, 0x64, 0xe8, 0x2c,
0xd5, 0x6a, 0x1e, 0x67, 0x91, 0x1a, 0xf7, 0x4c, 0x96, 0x96, 0x24, 0x04, 0x5a, 0xbe, 0x0e, 0x04,
0x18, 0x08, 0xdf, 0x3a, 0x73, 0x2f, 0xb8, 0xb9, 0x09, 0xdc, 0x6c, 0xa1, 0xf2, 0x71, 0x7f, 0xe2,
0x4c, 0xb7, 0x59, 0x85, 0x43, 0x66, 0xd0, 0x93, 0xc1, 0x6d, 0xc4, 0x55, 0x96, 0x8a, 0x71, 0x77,
0xe2, 0x4c, 0xfb, 0x07, 0x3b, 0x33, 0x84, 0x6e, 0x76, 0x51, 0xf0, 0x59, 0xa9, 0x42, 0x7f, 0x6f,
0x40, 0xfb, 0x48, 0xe7, 0xf2, 0x3f, 0x41, 0xeb, 0x3f, 0xae, 0x9f, 0x3c, 0x87, 0xa6, 0x5a, 0xc9,
0xf1, 0xd6, 0xa4, 0x39, 0xed, 0x1f, 0x10, 0xab, 0x79, 0x59, 0x7e, 0x63, 0x4c, 0x8b, 0xe9, 0x4b,
0xe8, 0x20, 0x48, 0x92, 0x50, 0x68, 0x07, 0x4a, 0x84, 0x72, 0xec, 0xa0, 0xc5, 0xc0, 0x5a, 0xa0,
0x94, 0x19, 0x11, 0x7d, 0x03, 0x80, 0xf4, 0x85, 0xb8, 0x9f, 0x1f, 0xe9, 0x2e, 0x46, 0x3c, 0x14,
0x08, 0x6a, 0x8f, 0xe1, 0x9b, 0xec, 0x40, 0xf3, 0x3d, 0x7b, 0x8b, 0x50, 0xf6, 0x98, 0x7e, 0x6a,
0x34, 0x44, 0xe4, 0xc6, 0x9e, 0x40, 0x0c, 0x7b, 0xcc, 0x52, 0xf4, 0x15, 0xf4, 0x4b, 0x5f, 0x92,
0x7c, 0x5e, 0x0f, 0xff, 0xa4, 0x1a, 0x1e, 0x55, 0x8a, 0x1c, 0x12, 0xe8, 0x16, 0x4c, 0x1d, 0x2d,
0xca, 0x42, 0xdb, 0x55, 0xfd, 0x24, 0x2f, 0xa0, 0x29, 0xc5, 0x3d, 0xc6, 0xef, 0x1f, 0x8c, 0x36,
0x9c, 0x64, 0x22, 0x72, 0x05, 0xd3, 0x0a, 0x64, 0x0f, 0x3a, 0x9e, 0x50, 0x3c, 0x58, 0x60, 0x56,
0x25, 0x40, 0xa8, 0x7a, 0x8c, 0x12, 0x66, 0x35, 0xe8, 0xb7, 0x36, 0xe2, 0x79, 0xe0, 0xe9, 0x88,
0x49, 0xe0, 0xd9, 0x92, 0xf5, 0x53, 0xe3, 0x86, 0x4d, 0xb4, 0x31, 0x37, 0x70, 0x43, 0x11, 0x7d,
0x0d, 0x83, 0x8a, 0x63, 0x49, 0xa6, 0xf5, 0x62, 0x1f, 0x0a, 0x6e, 0xab, 0x9d, 0xc1, 0x96, 0x99,
0x79, 0x49, 0x3e, 0xab, 0x1b, 0x6d, 0x5b, 0x23, 0x23, 0x2e, 0xf4, 0x4f, 0x00, 0xac, 0xfe, 0xc3,
0xd9, 0x4e, 0x61, 0xcb, 0x37, 0x72, 0x9b, 0xef, 0xb0, 0xe6, 0x46, 0xb2, 0x42, 0x4c, 0x7d, 0xd8,
0xc6, 0x7c, 0x7e, 0x5c, 0x8a, 0x74, 0x19, 0x88, 0x5f, 0xc8, 0x33, 0x68, 0x69, 0x19, 0x7a, 0xfb,
0x5b, 0x78, 0x14, 0x55, 0x27, 0xbe, 0x51, 0x9f, 0xf8, 0x5d, 0xe8, 0x9a, 0xd9, 0x11, 0x72, 0xdc,
0x9c, 0x34, 0xa7, 0x03, 0xb6, 0xa6, 0xe9, 0x1f, 0x8e, 0xfd, 0x14, 0x4c, 0xe9, 0x25, 0xa2, 0xce,
0xa3, 0x88, 0x92, 0x19, 0x74, 0x53, 0xe1, 0x8a, 0x20, 0x51, 0xba, 0x90, 0x2a, 0x88, 0xcc, 0xb0,
0x8f, 0xb9, 0xe2, 0x6c, 0xad, 0x43, 0x9e, 0x42, 0xe3, 0xec, 0x0a, 0x23, 0xf7, 0x0f, 0x3e, 0xb0,
0x9a, 0x67, 0x22, 0xbf, 0xe2, 0x8b, 0x4c, 0xb0, 0xc6, 0xd9, 0x15, 0x79, 0x01, 0xc3, 0x24, 0x15,
0xcb, 0x0b, 0xc5, 0x55, 0x26, 0x2b, 0x73, 0xbd, 0xc1, 0xa5, 0xaf, 0xa0, 0xcb, 0x0a, 0xa7, 0x7b,
0x95, 0x24, 0x4c, 0x53, 0x86, 0xf5, 0x24, 0xca, 0x04, 0xe8, 0x1b, 0xe8, 0x9d, 0xa7, 0xc1, 0x92,
0xbb, 0xf9, 0xd9, 0x15, 0xf9, 0x46, 0x07, 0xb3, 0xc4, 0x65, 0x7c, 0x27, 0x22, 0x6b, 0xfe, 0xa1,
0x35, 0x3f, 0xaf, 0x09, 0xd9, 0x86, 0x32, 0xcd, 0x61, 0x58, 0xd7, 0x20, 0x23, 0x68, 0x2b, 0xeb,
0x47, 0xb7, 0xda, 0x10, 0xa6, 0x1d, 0xa7, 0x91, 0x27, 0x56, 0xd8, 0x8e, 0x36, 0x2b, 0x48, 0xb3,
0xd8, 0xfc, 0xda, 0x62, 0xc3, 0x25, 0x6c, 0x60, 0x6a, 0x3d, 0x0a, 0x13, 0x95, 0x30, 0x2a, 0xca,
0xff, 0x2e, 0xf2, 0xca, 0x8a, 0xbe, 0xa8, 0x41, 0xe1, 0x54, 0xcc, 0x0b, 0xf5, 0x4a, 0x33, 0x66,
0xd0, 0x5b, 0x57, 0x64, 0x3f, 0xc3, 0x9d, 0xcd, 0xca, 0x59, 0xa9, 0x42, 0xa7, 0x40, 0xac, 0x97,
0xb9, 0x2f, 0xdc, 0xbb, 0xcb, 0xd5, 0xdb, 0x40, 0xe2, 0x11, 0x11, 0x69, 0x6a, 0x90, 0xef, 0x31,
0x7c, 0xd3, 0x1c, 0xfa, 0x73, 0x7d, 0x5a, 0x4d, 0xc3, 0xc8, 0x73, 0xd8, 0x76, 0xb3, 0x14, 0xd7,
0xb9, 0x59, 0xc8, 0x66, 0x53, 0xd4, 0x99, 0x64, 0x02, 0xfd, 0x50, 0x84, 0x49, 0x1c, 0x2f, 0x2e,
0x82, 0x5f, 0x85, 0xfd, 0x72, 0xab, 0x2c, 0x42, 0x61, 0x10, 0xca, 0xdb, 0x9f, 0x32, 0x91, 0x09,
0x54, 0x69, 0xa2, 0x4a, 0x8d, 0x47, 0x39, 0xf4, 0x98, 0xb8, 0xb7, 0xcb, 0x74, 0x04, 0x6d, 0xa9,
0x78, 0x5a, 0x04, 0x34, 0x84, 0x1e, 0x47, 0x11, 0x79, 0x36, 0x80, 0x7e, 0xea, 0xb1, 0x08, 0xe4,
0x71, 0xb9, 0x88, 0xba, 0x6c, 0x4d, 0x17, 0xc3, 0xdb, 0xc2, 0xf2, 0xf4, 0x93, 0x3e, 0x83, 0xfe,
0x0f, 0x95, 0xac, 0x08, 0xb4, 0xa4, 0xce, 0xc6, 0xc4, 0xc0, 0x37, 0xdd, 0x83, 0x1d, 0x26, 0x92,
0x45, 0x8e, 0x79, 0xd8, 0xfa, 0xca, 0x7b, 0xe4, 0x54, 0xef, 0x91, 0xce, 0x18, 0xd5, 0x8e, 0x62,
0x2f, 0x2f, 0xce, 0x85, 0xf3, 0x8f, 0xe7, 0xe2, 0xdf, 0x8e, 0x1d, 0x7d, 0x09, 0x70, 0x2a, 0xe7,
0x3c, 0xbb, 0xf5, 0xd5, 0xfb, 0x44, 0x9f, 0xb8, 0x53, 0xe9, 0x22, 0x95, 0x25, 0x98, 0x4c, 0x97,
0x55, 0x38, 0xf4, 0x35, 0x0c, 0x4f, 0xe5, 0x3b, 0x95, 0xcc, 0x71, 0x5f, 0xe7, 0x91, 0xab, 0xa7,
0x32, 0x90, 0x91, 0x4a, 0x5c, 0x84, 0x35, 0x8f, 0x5c, 0x6b, 0xb5, 0xc1, 0xa5, 0xbf, 0x39, 0xb0,
0x8d, 0x8d, 0xff, 0x7e, 0x25, 0xdc, 0x4c, 0xc5, 0xa9, 0x2e, 0xda, 0x4b, 0x83, 0xa5, 0x48, 0xed,
0x48, 0x58, 0x4a, 0x23, 0x7e, 0x93, 0x45, 0xee, 0x3b, 0x7d, 0xb8, 0xcc, 0x95, 0x5a, 0xd3, 0xf5,
0xb3, 0xde, 0xdc, 0x3c, 0xeb, 0x23, 0x68, 0x27, 0x3c, 0xe5, 0xa1, 0x5d, 0x0c, 0x86, 0xd0, 0x5c,
0xb1, 0x52, 0x29, 0xc7, 0x5b, 0x3f, 0x60, 0x86, 0xa0, 0x5f, 0xd9, 0xe5, 0x59, 0x1c, 0x1d, 0xdd,
0x2b, 0xf4, 0xea, 0x98, 0x3f, 0x1e, 0x74, 0x48, 0xa0, 0x75, 0x99, 0x27, 0xc5, 0x07, 0x87, 0x6f,
0xfa, 0x35, 0x0c, 0x6b, 0x86, 0x7a, 0xc9, 0xd4, 0xd6, 0xfe, 0xc3, 0x37, 0xcd, 0x6e, 0x7f, 0x1f,
0x46, 0xe7, 0x3c, 0xe5, 0x88, 0x44, 0x75, 0xa3, 0x7e, 0x09, 0x7d, 0x5c, 0x9b, 0xf6, 0xe4, 0x39,
0x8f, 0x9e, 0xbc, 0xaa, 0x9a, 0x86, 0x4a, 0xda, 0x00, 0x36, 0xc7, 0x35, 0x7d, 0xf4, 0xf4, 0xe7,
0x4f, 0x6e, 0x03, 0xe5, 0x67, 0xd7, 0x33, 0x37, 0x0e, 0xf7, 0x0f, 0x0f, 0xdd, 0x68, 0x1f, 0xff,
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 {
JrpcFuncBlacklist []string `protobuf:"bytes,7,rep,name=jrpcFuncBlacklist" json:"jrpcFuncBlacklist,omitempty"`
GrpcFuncBlacklist []string `protobuf:"bytes,8,rep,name=grpcFuncBlacklist" json:"grpcFuncBlacklist,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 配置
......
......@@ -136,6 +136,9 @@ const (
EventWalletCreateTx = 129
EventStoreList = 130
EventStoreListReply = 131
EventListBlockSeqCB = 132
EventGetSeqCBLastNum = 133
//exec
EventBlockChainQuery = 212
EventConsensusQuery = 213
......
......@@ -12,7 +12,7 @@ import (
"unicode"
"github.com/33cn/chain33/common/address"
proto "github.com/golang/protobuf/proto"
"github.com/golang/protobuf/proto"
)
func init() {
......@@ -113,17 +113,37 @@ func CallExecNewTx(execName, action string, param interface{}) ([]byte, error) {
func CallCreateTx(execName, action string, param Message) ([]byte, error) {
exec := LoadExecutorType(execName)
if exec == nil {
tlog.Error("callExecNewTx", "Error", "exec not found")
tlog.Error("CallCreateTx", "Error", "exec not found")
return nil, ErrNotSupport
}
// param is interface{type, var-nil}, check with nil always fail
if param == nil {
tlog.Error("callExecNewTx", "Error", "param in nil")
tlog.Error("CallCreateTx", "Error", "param in nil")
return nil, ErrInvalidParam
}
tx, err := exec.Create(action, param)
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 FormatTxEncode(execName, tx)
......@@ -655,7 +675,7 @@ func (base *ExecTypeBase) GetAction(action string) (Message, error) {
return nil, ErrActionNotSupport
}
//CreateTx 构造tx交易重构完成后删除
//CreateTx 通过json rpc 创建交易
func (base *ExecTypeBase) CreateTx(action string, msg json.RawMessage) (*Transaction, error) {
data, err := base.GetAction(action)
if err != nil {
......@@ -714,7 +734,10 @@ func (base *ExecTypeBase) CreateTransaction(action string, data Message) (tx *Tr
tymap := base.child.GetTypeMap()
if tyid, ok := tymap[action]; ok {
field.Set(reflect.ValueOf(tyid))
return &Transaction{Payload: Encode(value)}, nil
tx := &Transaction{
Payload: Encode(value),
}
return tx, nil
}
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 {
string encode = 3;
}
message BlockSeqCBs {
repeated BlockSeqCB items = 1;
}
message BlockSeq {
int64 num = 1;
BlockSequence seq = 2;
......
......@@ -58,6 +58,9 @@ grpcBindAddr="localhost:8802"
whitelist=["127.0.0.1"]
jrpcFuncWhitelist=["*"]
grpcFuncWhitelist=["*"]
enableTLS=false
certFile="cert.pem"
keyFile="key.pem"
[mempool]
poolCacheSize=102400
......
......@@ -6,7 +6,9 @@ package cli
import (
"fmt"
"net/http"
"os"
"strings"
"github.com/33cn/chain33/common/log"
"github.com/33cn/chain33/pluginmgr"
......@@ -43,6 +45,7 @@ var closeCmd = &cobra.Command{
func init() {
rootCmd.AddCommand(
commands.CertCmd(),
commands.AccountCmd(),
commands.BlockCmd(),
commands.BTYCmd(),
......@@ -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 :
func Run(RPCAddr, ParaName string) {
//test tls is enable
RPCAddr = testTLS(RPCAddr)
pluginmgr.AddCmd(rootCmd)
log.SetLogLevel("error")
types.S("RPCAddr", RPCAddr)
......
......@@ -135,7 +135,8 @@ func GetSeed(db dbm.DB, password string) (string, error) {
}
seed, err := AesgcmDecrypter([]byte(password), Encryptedseed)
if err != nil {
return "", err
seedlog.Error("GetSeed", "AesgcmDecrypter err", err)
return "", types.ErrInputPassword
}
return string(seed), nil
}
......
......@@ -30,16 +30,18 @@ func (wallet *Wallet) parseExpire(expire string) (int64, error) {
if len(expire) == 0 {
return 0, errors.New("Expire string should not be empty")
}
if expire[0] == 'H' && expire[1] == ':' {
txHeight, err := strconv.ParseInt(expire[2:], 10, 64)
if err != nil {
return 0, err
}
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")
}
if txHeight+types.TxHeightFlag < txHeight {
return 0, errors.New("txHeight overflow")
}
return txHeight + types.TxHeightFlag, nil
}
......@@ -538,8 +540,12 @@ func (wallet *Wallet) ProcSendToAddress(SendToAddress *types.ReqWalletSendToAddr
}
Balance := accounts[0].Balance
amount := SendToAddress.GetAmount()
//amount必须大于等于0
if amount < 0 {
return nil, types.ErrAmount
}
if !SendToAddress.IsToken {
if Balance < amount+wallet.FeeAmount {
if Balance-amount < wallet.FeeAmount {
return nil, types.ErrInsufficientBalance
}
} else {
......@@ -547,7 +553,6 @@ func (wallet *Wallet) ProcSendToAddress(SendToAddress *types.ReqWalletSendToAddr
if Balance < wallet.FeeAmount {
return nil, types.ErrInsufficientBalance
}
if nil == accTokenMap[SendToAddress.TokenSymbol] {
tokenAccDB, err := account.NewAccountDB("token", SendToAddress.TokenSymbol, nil)
if err != nil {
......
......@@ -479,9 +479,11 @@ func testProcSendToAddress(t *testing.T, wallet *Wallet) {
msg = wallet.client.NewMessage("wallet", types.EventWalletSendToAddress, withdraw)
wallet.client.Send(msg, true)
resp, err = wallet.client.Wait(msg)
require.NoError(t, err)
replyHash = resp.GetData().(*types.ReplyHash)
println("withdraw tx", "ReplyHash", common.ToHex(replyHash.Hash))
//返回ErrAmount错误
assert.Equal(t, string(err.Error()), types.ErrAmount.Error())
require.Error(t, err)
//replyHash = resp.GetData().(*types.ReplyHash)
//println("withdraw tx", "ReplyHash", common.ToHex(replyHash.Hash))
println("TestProcSendToAddress end")
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