Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
P
plugin
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
JIRA
JIRA
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
link33
plugin
Commits
2b61b2b1
Commit
2b61b2b1
authored
Jun 14, 2019
by
linj
Committed by
vipwzw
Jun 14, 2019
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
update chain33
parent
6252a9f1
Hide whitespace changes
Inline
Side-by-side
Showing
21 changed files
with
822 additions
and
157 deletions
+822
-157
blockstore.go
vendor/github.com/33cn/chain33/blockchain/blockstore.go
+169
-58
blockstore_test.go
vendor/github.com/33cn/chain33/blockchain/blockstore_test.go
+104
-3
chain.go
vendor/github.com/33cn/chain33/blockchain/chain.go
+2
-3
chain_test.go
vendor/github.com/33cn/chain33/blockchain/chain_test.go
+17
-0
proc.go
vendor/github.com/33cn/chain33/blockchain/proc.go
+31
-1
process.go
vendor/github.com/33cn/chain33/blockchain/process.go
+2
-2
sequences.go
vendor/github.com/33cn/chain33/blockchain/sequences.go
+12
-0
mock_blockchain_test.go
...or/github.com/33cn/chain33/client/mock_blockchain_test.go
+12
-0
api.go
vendor/github.com/33cn/chain33/client/mocks/api.go
+46
-0
queueprotocol.go
vendor/github.com/33cn/chain33/client/queueprotocol.go
+33
-0
queueprotocol_test.go
vendor/github.com/33cn/chain33/client/queueprotocol_test.go
+23
-0
queueprotocolapi.go
vendor/github.com/33cn/chain33/client/queueprotocolapi.go
+6
-0
base.go
vendor/github.com/33cn/chain33/system/mempool/base.go
+24
-1
cache.go
vendor/github.com/33cn/chain33/system/mempool/cache.go
+14
-1
eventprocess.go
...or/github.com/33cn/chain33/system/mempool/eventprocess.go
+10
-0
mempool_test.go
...or/github.com/33cn/chain33/system/mempool/mempool_test.go
+91
-0
shorthashtx.go
vendor/github.com/33cn/chain33/system/mempool/shorthashtx.go
+62
-0
event.go
vendor/github.com/33cn/chain33/types/event.go
+14
-2
transaction.proto
vendor/github.com/33cn/chain33/types/proto/transaction.proto
+7
-2
transaction.pb.go
vendor/github.com/33cn/chain33/types/transaction.pb.go
+135
-84
tx.go
vendor/github.com/33cn/chain33/types/tx.go
+8
-0
No files found.
vendor/github.com/33cn/chain33/blockchain/blockstore.go
View file @
2b61b2b1
...
...
@@ -25,17 +25,20 @@ import (
//var
var
(
blockLastHeight
=
[]
byte
(
"blockLastHeight"
)
bodyP
er
fix
=
[]
byte
(
"Body:"
)
bodyP
re
fix
=
[]
byte
(
"Body:"
)
LastSequence
=
[]
byte
(
"LastSequence"
)
headerP
er
fix
=
[]
byte
(
"Header:"
)
heightToHeaderP
er
fix
=
[]
byte
(
"HH:"
)
hashP
er
fix
=
[]
byte
(
"Hash:"
)
tdP
er
fix
=
[]
byte
(
"TD:"
)
heightToHashKeyP
er
fix
=
[]
byte
(
"Height:"
)
headerP
re
fix
=
[]
byte
(
"Header:"
)
heightToHeaderP
re
fix
=
[]
byte
(
"HH:"
)
hashP
re
fix
=
[]
byte
(
"Hash:"
)
tdP
re
fix
=
[]
byte
(
"TD:"
)
heightToHashKeyP
re
fix
=
[]
byte
(
"Height:"
)
seqToHashKey
=
[]
byte
(
"Seq:"
)
HashToSeqP
er
fix
=
[]
byte
(
"HashToSeq:"
)
HashToSeqP
re
fix
=
[]
byte
(
"HashToSeq:"
)
seqCBPrefix
=
[]
byte
(
"SCB:"
)
seqCBLastNumPrefix
=
[]
byte
(
"SCBL:"
)
paraSeqToHashKey
=
[]
byte
(
"ParaSeq:"
)
HashToParaSeqPrefix
=
[]
byte
(
"HashToParaSeq:"
)
LastParaSequence
=
[]
byte
(
"LastParaSequence"
)
storeLog
=
chainlog
.
New
(
"submodule"
,
"store"
)
AddBlock
int64
=
1
DelBlock
int64
=
2
...
...
@@ -44,15 +47,15 @@ var (
//GetLocalDBKeyList 获取本地键值列表
func
GetLocalDBKeyList
()
[][]
byte
{
return
[][]
byte
{
blockLastHeight
,
bodyP
erfix
,
LastSequence
,
headerPerfix
,
heightToHeaderPer
fix
,
hashP
erfix
,
tdPerfix
,
heightToHashKeyPerfix
,
seqToHashKey
,
HashToSeqPer
fix
,
seqCBPrefix
,
seqCBLastNumPrefix
,
tempBlockKey
,
lastTempBlockKey
,
blockLastHeight
,
bodyP
refix
,
LastSequence
,
headerPrefix
,
heightToHeaderPre
fix
,
hashP
refix
,
tdPrefix
,
heightToHashKeyPrefix
,
seqToHashKey
,
HashToSeqPre
fix
,
seqCBPrefix
,
seqCBLastNumPrefix
,
tempBlockKey
,
lastTempBlockKey
,
LastParaSequence
,
}
}
//存储block hash对应的blockbody信息
func
calcHashToBlockBodyKey
(
hash
[]
byte
)
[]
byte
{
return
append
(
bodyP
er
fix
,
hash
...
)
return
append
(
bodyP
re
fix
,
hash
...
)
}
//并发访问的可能性(每次开辟新内存)
...
...
@@ -61,42 +64,65 @@ func calcSeqCBKey(name []byte) []byte {
}
//并发访问的可能性(每次开辟新内存)
func
ca
cl
SeqCBLastNumKey
(
name
[]
byte
)
[]
byte
{
func
ca
lc
SeqCBLastNumKey
(
name
[]
byte
)
[]
byte
{
return
append
(
append
([]
byte
{},
seqCBLastNumPrefix
...
),
name
...
)
}
//存储block hash对应的header信息
func
calcHashToBlockHeaderKey
(
hash
[]
byte
)
[]
byte
{
return
append
(
headerP
er
fix
,
hash
...
)
return
append
(
headerP
re
fix
,
hash
...
)
}
func
calcHeightToBlockHeaderKey
(
height
int64
)
[]
byte
{
return
append
(
heightToHeaderP
er
fix
,
[]
byte
(
fmt
.
Sprintf
(
"%012d"
,
height
))
...
)
return
append
(
heightToHeaderP
re
fix
,
[]
byte
(
fmt
.
Sprintf
(
"%012d"
,
height
))
...
)
}
//存储block hash对应的block height
func
calcHashToHeightKey
(
hash
[]
byte
)
[]
byte
{
return
append
(
hashP
er
fix
,
hash
...
)
return
append
(
hashP
re
fix
,
hash
...
)
}
//存储block hash对应的block总难度TD
func
calcHashToTdKey
(
hash
[]
byte
)
[]
byte
{
return
append
(
tdP
er
fix
,
hash
...
)
return
append
(
tdP
re
fix
,
hash
...
)
}
//存储block height 对应的block hash
func
calcHeightToHashKey
(
height
int64
)
[]
byte
{
return
append
(
heightToHashKeyP
er
fix
,
[]
byte
(
fmt
.
Sprintf
(
"%v"
,
height
))
...
)
return
append
(
heightToHashKeyP
re
fix
,
[]
byte
(
fmt
.
Sprintf
(
"%v"
,
height
))
...
)
}
//存储block操作序列号对应的block hash,KEY=Seq:sequence
func
calcSequenceToHashKey
(
sequence
int64
)
[]
byte
{
func
calcSequenceToHashKey
(
sequence
int64
,
isPara
bool
)
[]
byte
{
if
isPara
{
return
append
(
paraSeqToHashKey
,
[]
byte
(
fmt
.
Sprintf
(
"%v"
,
sequence
))
...
)
}
return
append
(
seqToHashKey
,
[]
byte
(
fmt
.
Sprintf
(
"%v"
,
sequence
))
...
)
}
//存储block hash对应的seq序列号,KEY=Seq:sequence,只用于平行链addblock操作,方便delblock回退是查找对应seq的hash
func
calcHashToSequenceKey
(
hash
[]
byte
)
[]
byte
{
return
append
(
HashToSeqPerfix
,
hash
...
)
func
calcHashToSequenceKey
(
hash
[]
byte
,
isPara
bool
)
[]
byte
{
if
isPara
{
return
append
(
HashToParaSeqPrefix
,
hash
...
)
}
return
append
(
HashToSeqPrefix
,
hash
...
)
}
func
calcLastSeqKey
(
isPara
bool
)
[]
byte
{
if
isPara
{
return
LastParaSequence
}
return
LastSequence
}
//存储block hash对应的seq序列号,KEY=Seq:sequence,只用于平行链addblock操作,方便delblock回退是查找对应seq的hash
func
calcHashToMainSequenceKey
(
hash
[]
byte
)
[]
byte
{
return
append
(
HashToSeqPrefix
,
hash
...
)
}
//存储block操作序列号对应的block hash,KEY=MainSeq:sequence
func
calcMainSequenceToHashKey
(
sequence
int64
)
[]
byte
{
return
append
(
seqToHashKey
,
[]
byte
(
fmt
.
Sprintf
(
"%v"
,
sequence
))
...
)
}
//BlockStore 区块存储
...
...
@@ -106,7 +132,8 @@ type BlockStore struct {
height
int64
lastBlock
*
types
.
Block
lastheaderlock
sync
.
Mutex
chain
*
BlockChain
saveSequence
bool
isParaChain
bool
}
//NewBlockStore new
...
...
@@ -122,7 +149,10 @@ func NewBlockStore(chain *BlockChain, db dbm.DB, client queue.Client) *BlockStor
height
:
height
,
db
:
db
,
client
:
client
,
chain
:
chain
,
}
if
chain
!=
nil
{
blockStore
.
saveSequence
=
chain
.
isRecordBlockSequence
blockStore
.
isParaChain
=
chain
.
isParaChain
}
if
height
==
-
1
{
chainlog
.
Info
(
"load block height error, may be init database"
,
"height"
,
height
)
...
...
@@ -558,7 +588,7 @@ func (bs *BlockStore) SaveBlock(storeBatch dbm.Batch, blockdetail *types.BlockDe
//存储block height和block hash的对应关系,便于通过height查询block
storeBatch
.
Set
(
calcHeightToHashKey
(
height
),
hash
)
if
bs
.
chain
.
isRecordBlockSequence
||
bs
.
chain
.
isParaChain
{
if
bs
.
saveSequence
||
bs
.
isParaChain
{
//存储记录block序列执行的type add
lastSequence
,
err
=
bs
.
saveBlockSequence
(
storeBatch
,
hash
,
height
,
AddBlock
,
sequence
)
if
err
!=
nil
{
...
...
@@ -587,7 +617,7 @@ func (bs *BlockStore) DelBlock(storeBatch dbm.Batch, blockdetail *types.BlockDet
storeBatch
.
Delete
(
calcHeightToHashKey
(
height
))
storeBatch
.
Delete
(
calcHeightToBlockHeaderKey
(
height
))
if
bs
.
chain
.
isRecordBlockSequence
||
bs
.
chain
.
isParaChain
{
if
bs
.
saveSequence
||
bs
.
isParaChain
{
//存储记录block序列执行的type del
lastSequence
,
err
:=
bs
.
saveBlockSequence
(
storeBatch
,
hash
,
height
,
DelBlock
,
sequence
)
if
err
!=
nil
{
...
...
@@ -917,7 +947,8 @@ func (bs *BlockStore) dbMaybeStoreBlock(blockdetail *types.BlockDetail, sync boo
//LoadBlockLastSequence 获取当前最新的block操作序列号
func
(
bs
*
BlockStore
)
LoadBlockLastSequence
()
(
int64
,
error
)
{
bytes
,
err
:=
bs
.
db
.
Get
(
LastSequence
)
lastKey
:=
calcLastSeqKey
(
bs
.
isParaChain
)
bytes
,
err
:=
bs
.
db
.
Get
(
lastKey
)
if
bytes
==
nil
||
err
!=
nil
{
if
err
!=
dbm
.
ErrNotFoundInDb
{
storeLog
.
Error
(
"LoadBlockLastSequence"
,
"error"
,
err
)
...
...
@@ -927,13 +958,25 @@ func (bs *BlockStore) LoadBlockLastSequence() (int64, error) {
return
decodeHeight
(
bytes
)
}
//LoadBlockLastMainSequence 获取当前最新的block操作序列号
func
(
bs
*
BlockStore
)
LoadBlockLastMainSequence
()
(
int64
,
error
)
{
bytes
,
err
:=
bs
.
db
.
Get
(
LastSequence
)
if
bytes
==
nil
||
err
!=
nil
{
if
err
!=
dbm
.
ErrNotFoundInDb
{
storeLog
.
Error
(
"LoadBlockLastMainSequence"
,
"error"
,
err
)
}
return
-
1
,
types
.
ErrHeightNotExist
}
return
decodeHeight
(
bytes
)
}
func
(
bs
*
BlockStore
)
setSeqCBLastNum
(
name
[]
byte
,
num
int64
)
error
{
return
bs
.
db
.
SetSync
(
ca
cl
SeqCBLastNumKey
(
name
),
types
.
Encode
(
&
types
.
Int64
{
Data
:
num
}))
return
bs
.
db
.
SetSync
(
ca
lc
SeqCBLastNumKey
(
name
),
types
.
Encode
(
&
types
.
Int64
{
Data
:
num
}))
}
//Seq的合法值从0开始的,所以没有获取到或者获取失败都应该返回-1
func
(
bs
*
BlockStore
)
getSeqCBLastNum
(
name
[]
byte
)
int64
{
bytes
,
err
:=
bs
.
db
.
Get
(
ca
cl
SeqCBLastNumKey
(
name
))
bytes
,
err
:=
bs
.
db
.
Get
(
ca
lc
SeqCBLastNumKey
(
name
))
if
bytes
==
nil
||
err
!=
nil
{
if
err
!=
dbm
.
ErrNotFoundInDb
{
storeLog
.
Error
(
"getSeqCBLastNum"
,
"error"
,
err
)
...
...
@@ -950,14 +993,14 @@ func (bs *BlockStore) getSeqCBLastNum(name []byte) int64 {
}
//SaveBlockSequence 存储block 序列执行的类型用于blockchain的恢复
//获取当前的序列号,将此序列号加1存储本block的hash ,当主链使能isRecordBlockSequence
// 平行链使能isParaChain时,sequence序列号是传入的
//获取当前的序列号,将此序列号加1存储本block的hash ,当使能isRecordBlockSequence
//平行链使能isParaChain时,而外保存主链的 sequence
// 需要保存
// seq->hash, hash->seq, last_seq
// 平行链需要主链的对应信息
func
(
bs
*
BlockStore
)
saveBlockSequence
(
storeBatch
dbm
.
Batch
,
hash
[]
byte
,
height
int64
,
Type
int64
,
sequence
int64
)
(
int64
,
error
)
{
var
blockSequence
types
.
BlockSequence
var
newSequence
int64
if
bs
.
chain
.
isRecordBlockSequence
{
if
bs
.
saveSequence
{
Sequence
,
err
:=
bs
.
LoadBlockLastSequence
()
if
err
!=
nil
{
storeLog
.
Error
(
"SaveBlockSequence"
,
"LoadBlockLastSequence err"
,
err
)
...
...
@@ -969,31 +1012,52 @@ func (bs *BlockStore) saveBlockSequence(storeBatch dbm.Batch, hash []byte, heigh
newSequence
=
Sequence
+
1
//开启isRecordBlockSequence功能必须从0开始同步数据,不允许从非0高度开启此功能
if
newSequence
==
0
&&
height
!=
0
{
storeLog
.
Error
(
"isRecordBlockSequence is true must Synchronizing data from zero block"
,
"height"
,
height
)
storeLog
.
Error
(
"isRecordBlockSequence is true must Synchronizing data from zero block"
,
"height"
,
height
,
"seq"
,
newSequence
)
panic
(
errors
.
New
(
"isRecordBlockSequence is true must Synchronizing data from zero block"
))
}
}
else
if
bs
.
chain
.
isParaChain
{
newSequence
=
sequence
// seq->hash
var
blockSequence
types
.
BlockSequence
blockSequence
.
Hash
=
hash
blockSequence
.
Type
=
Type
BlockSequenceByte
,
err
:=
proto
.
Marshal
(
&
blockSequence
)
if
err
!=
nil
{
storeLog
.
Error
(
"SaveBlockSequence Marshal BlockSequence"
,
"hash"
,
common
.
ToHex
(
hash
),
"error"
,
err
)
return
newSequence
,
err
}
storeBatch
.
Set
(
calcSequenceToHashKey
(
newSequence
,
bs
.
isParaChain
),
BlockSequenceByte
)
sequenceBytes
:=
types
.
Encode
(
&
types
.
Int64
{
Data
:
newSequence
})
// hash->seq 只记录add block时的hash和seq对应关系
if
Type
==
AddBlock
{
storeBatch
.
Set
(
calcHashToSequenceKey
(
hash
,
bs
.
isParaChain
),
sequenceBytes
)
}
// 记录last seq
storeBatch
.
Set
(
calcLastSeqKey
(
bs
.
isParaChain
),
sequenceBytes
)
}
if
!
bs
.
isParaChain
{
return
newSequence
,
nil
}
mainSeq
:=
sequence
var
blockSequence
types
.
BlockSequence
blockSequence
.
Hash
=
hash
blockSequence
.
Type
=
Type
BlockSequenceByte
,
err
:=
proto
.
Marshal
(
&
blockSequence
)
if
err
!=
nil
{
storeLog
.
Error
(
"SaveBlockSequence Marshal BlockSequence"
,
"hash"
,
common
.
ToHex
(
hash
),
"error"
,
err
)
return
newSequence
,
err
}
storeBatch
.
Set
(
calcMainSequenceToHashKey
(
mainSeq
),
BlockSequenceByte
)
// seq->hash
storeBatch
.
Set
(
calcSequenceToHashKey
(
newSequence
),
BlockSequenceByte
)
//parachain hash->seq 只记录add block时的hash和seq对应关系
// hash->seq 只记录add block时的hash和seq对应关系
sequenceBytes
:=
types
.
Encode
(
&
types
.
Int64
{
Data
:
mainSeq
})
if
Type
==
AddBlock
{
Sequencebytes
:=
types
.
Encode
(
&
types
.
Int64
{
Data
:
newSequence
})
storeBatch
.
Set
(
calcHashToSequenceKey
(
hash
),
Sequencebytes
)
storeBatch
.
Set
(
calcHashToMainSequenceKey
(
hash
),
sequenceBytes
)
}
Sequencebytes
:=
types
.
Encode
(
&
types
.
Int64
{
Data
:
newSequence
})
storeBatch
.
Set
(
LastSequence
,
Sequencebytes
)
storeBatch
.
Set
(
LastSequence
,
sequenceBytes
)
return
newSequence
,
nil
}
...
...
@@ -1008,11 +1072,20 @@ func (bs *BlockStore) LoadBlockBySequence(Sequence int64) (*types.BlockDetail, i
return
bs
.
loadBlockByHash
(
BlockSequence
.
Hash
)
}
//LoadBlockByMainSequence 通过main seq高度获取BlockDetail信息
func
(
bs
*
BlockStore
)
LoadBlockByMainSequence
(
sequence
int64
)
(
*
types
.
BlockDetail
,
int
,
error
)
{
//首先通过Sequence序列号获取对应的blockhash和操作类型从db中
BlockSequence
,
err
:=
bs
.
GetBlockByMainSequence
(
sequence
)
if
err
!=
nil
{
return
nil
,
0
,
err
}
return
bs
.
loadBlockByHash
(
BlockSequence
.
Hash
)
}
//GetBlockSequence 从db数据库中获取指定Sequence对应的block序列操作信息
func
(
bs
*
BlockStore
)
GetBlockSequence
(
Sequence
int64
)
(
*
types
.
BlockSequence
,
error
)
{
var
blockSeq
types
.
BlockSequence
blockSeqByte
,
err
:=
bs
.
db
.
Get
(
calcSequenceToHashKey
(
Sequence
))
blockSeqByte
,
err
:=
bs
.
db
.
Get
(
calcSequenceToHashKey
(
Sequence
,
bs
.
isParaChain
))
if
blockSeqByte
==
nil
||
err
!=
nil
{
if
err
!=
dbm
.
ErrNotFoundInDb
{
storeLog
.
Error
(
"GetBlockSequence"
,
"error"
,
err
)
...
...
@@ -1028,10 +1101,29 @@ func (bs *BlockStore) GetBlockSequence(Sequence int64) (*types.BlockSequence, er
return
&
blockSeq
,
nil
}
//GetSequenceByHash 通过block还是获取对应的seq,只提供给parachain使用
//GetBlockByMainSequence 从db数据库中获取指定Sequence对应的block序列操作信息
func
(
bs
*
BlockStore
)
GetBlockByMainSequence
(
sequence
int64
)
(
*
types
.
BlockSequence
,
error
)
{
var
blockSeq
types
.
BlockSequence
blockSeqByte
,
err
:=
bs
.
db
.
Get
(
calcMainSequenceToHashKey
(
sequence
))
if
blockSeqByte
==
nil
||
err
!=
nil
{
if
err
!=
dbm
.
ErrNotFoundInDb
{
storeLog
.
Error
(
"GetBlockByMainSequence"
,
"error"
,
err
)
}
return
nil
,
types
.
ErrHeightNotExist
}
err
=
proto
.
Unmarshal
(
blockSeqByte
,
&
blockSeq
)
if
err
!=
nil
{
storeLog
.
Error
(
"GetBlockByMainSequence"
,
"err"
,
err
)
return
nil
,
err
}
return
&
blockSeq
,
nil
}
//GetSequenceByHash 通过block还是获取对应的seq
func
(
bs
*
BlockStore
)
GetSequenceByHash
(
hash
[]
byte
)
(
int64
,
error
)
{
var
seq
types
.
Int64
seqbytes
,
err
:=
bs
.
db
.
Get
(
calcHashToSequenceKey
(
hash
))
seqbytes
,
err
:=
bs
.
db
.
Get
(
calcHashToSequenceKey
(
hash
,
bs
.
isParaChain
))
if
seqbytes
==
nil
||
err
!=
nil
{
if
err
!=
dbm
.
ErrNotFoundInDb
{
storeLog
.
Error
(
"GetSequenceByHash"
,
"error"
,
err
)
...
...
@@ -1047,6 +1139,25 @@ func (bs *BlockStore) GetSequenceByHash(hash []byte) (int64, error) {
return
seq
.
Data
,
nil
}
//GetMainSequenceByHash 通过block还是获取对应的seq,只提供给parachain使用
func
(
bs
*
BlockStore
)
GetMainSequenceByHash
(
hash
[]
byte
)
(
int64
,
error
)
{
var
seq
types
.
Int64
seqbytes
,
err
:=
bs
.
db
.
Get
(
calcHashToMainSequenceKey
(
hash
))
if
seqbytes
==
nil
||
err
!=
nil
{
if
err
!=
dbm
.
ErrNotFoundInDb
{
storeLog
.
Error
(
"GetMainSequenceByHash"
,
"error"
,
err
)
}
return
-
1
,
types
.
ErrHashNotExist
}
err
=
types
.
Decode
(
seqbytes
,
&
seq
)
if
err
!=
nil
{
storeLog
.
Error
(
"GetMainSequenceByHash types.Decode"
,
"error"
,
err
)
return
-
1
,
types
.
ErrUnmarshal
}
return
seq
.
Data
,
nil
}
//GetDbVersion 获取blockchain的数据库版本号
func
(
bs
*
BlockStore
)
GetDbVersion
()
int64
{
ver
:=
types
.
Int64
{}
...
...
@@ -1128,38 +1239,38 @@ func (bs *BlockStore) SetStoreUpgradeMeta(meta *types.UpgradeMeta) error {
return
bs
.
db
.
SetSync
(
version
.
StoreDBMeta
,
verByte
)
}
//
isRecordBlockSequence
配置的合法性检测
func
(
bs
*
BlockStore
)
isRecordBlockSequenceValid
(
chain
*
BlockChain
)
{
//
SequenceMustValid
配置的合法性检测
func
(
bs
*
BlockStore
)
SequenceMustValid
(
recordSequence
bool
)
{
lastHeight
:=
bs
.
Height
()
lastSequence
,
err
:=
bs
.
LoadBlockLastSequence
()
if
err
!=
nil
{
if
err
!=
types
.
ErrHeightNotExist
{
storeLog
.
Error
(
"
isRecordBlockSequence
Valid"
,
"LoadBlockLastSequence err"
,
err
)
storeLog
.
Error
(
"
SequenceMust
Valid"
,
"LoadBlockLastSequence err"
,
err
)
panic
(
err
)
}
}
//使能isRecordBlockSequence时的检测
if
chain
.
isRecordBlock
Sequence
{
if
record
Sequence
{
//中途开启isRecordBlockSequence报错
if
lastSequence
==
-
1
&&
lastHeight
!=
-
1
{
storeLog
.
Error
(
"
isRecordBlockSequence
Valid"
,
"lastHeight"
,
lastHeight
,
"lastSequence"
,
lastSequence
)
storeLog
.
Error
(
"
SequenceMust
Valid"
,
"lastHeight"
,
lastHeight
,
"lastSequence"
,
lastSequence
)
panic
(
"isRecordBlockSequence is true must Synchronizing data from zero block"
)
}
//lastSequence 必须大于等于lastheight
if
lastHeight
>
lastSequence
{
storeLog
.
Error
(
"
isRecordBlockSequence
Valid"
,
"lastHeight"
,
lastHeight
,
"lastSequence"
,
lastSequence
)
storeLog
.
Error
(
"
SequenceMust
Valid"
,
"lastHeight"
,
lastHeight
,
"lastSequence"
,
lastSequence
)
panic
(
"lastSequence must greater than or equal to lastHeight"
)
}
//通过lastSequence获取对应的blockhash != lastHeader.hash 报错
if
lastSequence
!=
-
1
{
blockSequence
,
err
:=
bs
.
GetBlockSequence
(
lastSequence
)
if
err
!=
nil
{
storeLog
.
Error
(
"
isRecordBlockSequence
Valid"
,
"lastSequence"
,
lastSequence
,
"GetBlockSequence err"
,
err
)
storeLog
.
Error
(
"
SequenceMust
Valid"
,
"lastSequence"
,
lastSequence
,
"GetBlockSequence err"
,
err
)
panic
(
err
)
}
lastHeader
:=
bs
.
LastHeader
()
if
!
bytes
.
Equal
(
lastHeader
.
Hash
,
blockSequence
.
Hash
)
{
storeLog
.
Error
(
"
isRecordBlockSequence
Valid:"
,
"lastHeight"
,
lastHeight
,
"lastSequence"
,
lastSequence
,
"lastHeader.Hash"
,
common
.
ToHex
(
lastHeader
.
Hash
),
"blockSequence.Hash"
,
common
.
ToHex
(
blockSequence
.
Hash
))
storeLog
.
Error
(
"
SequenceMust
Valid:"
,
"lastHeight"
,
lastHeight
,
"lastSequence"
,
lastSequence
,
"lastHeader.Hash"
,
common
.
ToHex
(
lastHeader
.
Hash
),
"blockSequence.Hash"
,
common
.
ToHex
(
blockSequence
.
Hash
))
panic
(
"The hash values of lastSequence and lastHeight are different."
)
}
}
...
...
@@ -1167,7 +1278,7 @@ func (bs *BlockStore) isRecordBlockSequenceValid(chain *BlockChain) {
}
//去使能isRecordBlockSequence时的检测
if
lastSequence
!=
-
1
{
storeLog
.
Error
(
"
isRecordBlockSequence
Valid"
,
"lastSequence"
,
lastSequence
)
storeLog
.
Error
(
"
SequenceMust
Valid"
,
"lastSequence"
,
lastSequence
)
panic
(
"can not disable isRecordBlockSequence"
)
}
}
vendor/github.com/33cn/chain33/blockchain/blockstore_test.go
View file @
2b61b2b1
package
blockchain
_test
package
blockchain
import
(
"testing"
...
...
@@ -6,7 +6,6 @@ import (
"io/ioutil"
"os"
"github.com/33cn/chain33/blockchain"
dbm
"github.com/33cn/chain33/common/db"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
...
...
@@ -20,7 +19,7 @@ func TestGetStoreUpgradeMeta(t *testing.T) {
blockStoreDB
:=
dbm
.
NewDB
(
"blockchain"
,
"leveldb"
,
dir
,
100
)
blockStore
:=
blockchain
.
NewBlockStore
(
nil
,
blockStoreDB
,
nil
)
blockStore
:=
NewBlockStore
(
nil
,
blockStoreDB
,
nil
)
require
.
NotNil
(
t
,
blockStore
)
meta
,
err
:=
blockStore
.
GetStoreUpgradeMeta
()
...
...
@@ -34,3 +33,105 @@ func TestGetStoreUpgradeMeta(t *testing.T) {
require
.
NoError
(
t
,
err
)
require
.
Equal
(
t
,
meta
.
Version
,
"1.0.0"
)
}
func
TestSeqSaveAndGet
(
t
*
testing
.
T
)
{
dir
,
err
:=
ioutil
.
TempDir
(
""
,
"example"
)
assert
.
Nil
(
t
,
err
)
defer
os
.
RemoveAll
(
dir
)
// clean up
os
.
RemoveAll
(
dir
)
//删除已存在目录
blockStoreDB
:=
dbm
.
NewDB
(
"blockchain"
,
"leveldb"
,
dir
,
100
)
blockStore
:=
NewBlockStore
(
nil
,
blockStoreDB
,
nil
)
assert
.
NotNil
(
t
,
blockStore
)
blockStore
.
saveSequence
=
true
blockStore
.
isParaChain
=
false
newBatch
:=
blockStore
.
NewBatch
(
true
)
seq
,
err
:=
blockStore
.
saveBlockSequence
(
newBatch
,
[]
byte
(
"s0"
),
0
,
1
,
0
)
assert
.
Nil
(
t
,
err
)
assert
.
Equal
(
t
,
int64
(
0
),
seq
)
err
=
newBatch
.
Write
()
assert
.
Nil
(
t
,
err
)
newBatch
=
blockStore
.
NewBatch
(
true
)
seq
,
err
=
blockStore
.
saveBlockSequence
(
newBatch
,
[]
byte
(
"s1"
),
1
,
1
,
0
)
assert
.
Nil
(
t
,
err
)
assert
.
Equal
(
t
,
int64
(
1
),
seq
)
err
=
newBatch
.
Write
()
assert
.
Nil
(
t
,
err
)
s
,
err
:=
blockStore
.
LoadBlockLastSequence
()
assert
.
Nil
(
t
,
err
)
assert
.
Equal
(
t
,
int64
(
1
),
s
)
s2
,
err
:=
blockStore
.
GetBlockSequence
(
s
)
assert
.
Nil
(
t
,
err
)
assert
.
Equal
(
t
,
[]
byte
(
"s1"
),
s2
.
Hash
)
s3
,
err
:=
blockStore
.
GetSequenceByHash
([]
byte
(
"s1"
))
assert
.
Nil
(
t
,
err
)
assert
.
Equal
(
t
,
int64
(
1
),
s3
)
}
func
TestParaSeqSaveAndGet
(
t
*
testing
.
T
)
{
dir
,
err
:=
ioutil
.
TempDir
(
""
,
"example"
)
assert
.
Nil
(
t
,
err
)
defer
os
.
RemoveAll
(
dir
)
// clean up
os
.
RemoveAll
(
dir
)
//删除已存在目录
blockStoreDB
:=
dbm
.
NewDB
(
"blockchain"
,
"leveldb"
,
dir
,
100
)
blockStore
:=
NewBlockStore
(
nil
,
blockStoreDB
,
nil
)
assert
.
NotNil
(
t
,
blockStore
)
blockStore
.
saveSequence
=
true
blockStore
.
isParaChain
=
true
newBatch
:=
blockStore
.
NewBatch
(
true
)
seq
,
err
:=
blockStore
.
saveBlockSequence
(
newBatch
,
[]
byte
(
"s0"
),
0
,
1
,
1
)
assert
.
Nil
(
t
,
err
)
assert
.
Equal
(
t
,
int64
(
0
),
seq
)
err
=
newBatch
.
Write
()
assert
.
Nil
(
t
,
err
)
newBatch
=
blockStore
.
NewBatch
(
true
)
seq
,
err
=
blockStore
.
saveBlockSequence
(
newBatch
,
[]
byte
(
"s1"
),
1
,
1
,
10
)
assert
.
Nil
(
t
,
err
)
assert
.
Equal
(
t
,
int64
(
1
),
seq
)
err
=
newBatch
.
Write
()
assert
.
Nil
(
t
,
err
)
s
,
err
:=
blockStore
.
LoadBlockLastSequence
()
assert
.
Nil
(
t
,
err
)
assert
.
Equal
(
t
,
int64
(
1
),
s
)
s2
,
err
:=
blockStore
.
GetBlockSequence
(
s
)
assert
.
Nil
(
t
,
err
)
assert
.
Equal
(
t
,
[]
byte
(
"s1"
),
s2
.
Hash
)
s3
,
err
:=
blockStore
.
GetSequenceByHash
([]
byte
(
"s1"
))
assert
.
Nil
(
t
,
err
)
assert
.
Equal
(
t
,
int64
(
1
),
s3
)
s4
,
err
:=
blockStore
.
GetMainSequenceByHash
([]
byte
(
"s1"
))
assert
.
Nil
(
t
,
err
)
assert
.
Equal
(
t
,
int64
(
10
),
s4
)
s5
,
err
:=
blockStore
.
LoadBlockLastMainSequence
()
assert
.
Nil
(
t
,
err
)
assert
.
Equal
(
t
,
int64
(
10
),
s5
)
s6
,
err
:=
blockStore
.
GetBlockByMainSequence
(
1
)
assert
.
Nil
(
t
,
err
)
assert
.
Equal
(
t
,
[]
byte
(
"s0"
),
s6
.
Hash
)
chain
:=
&
BlockChain
{
blockStore
:
blockStore
,
}
s7
,
err
:=
chain
.
ProcGetMainSeqByHash
([]
byte
(
"s0"
))
assert
.
Nil
(
t
,
err
)
assert
.
Equal
(
t
,
int64
(
1
),
s7
)
_
,
err
=
chain
.
ProcGetMainSeqByHash
([]
byte
(
"s0-not-exist"
))
assert
.
NotNil
(
t
,
err
)
}
vendor/github.com/33cn/chain33/blockchain/chain.go
View file @
2b61b2b1
...
...
@@ -245,9 +245,8 @@ func (chain *BlockChain) GetOrphanPool() *OrphanPool {
//InitBlockChain 区块链初始化
func
(
chain
*
BlockChain
)
InitBlockChain
()
{
//isRecordBlockSequence配置的合法性检测
if
!
chain
.
cfg
.
IsParaChain
{
chain
.
blockStore
.
isRecordBlockSequenceValid
(
chain
)
}
chain
.
blockStore
.
SequenceMustValid
(
chain
.
isRecordBlockSequence
)
//先缓存最新的128个block信息到cache中
curheight
:=
chain
.
GetBlockHeight
()
if
types
.
IsEnable
(
"TxHeight"
)
{
...
...
vendor/github.com/33cn/chain33/blockchain/chain_test.go
View file @
2b61b2b1
...
...
@@ -19,6 +19,7 @@ import (
"github.com/33cn/chain33/common/log"
"github.com/33cn/chain33/common/log/log15"
"github.com/33cn/chain33/common/merkle"
"github.com/33cn/chain33/queue"
_
"github.com/33cn/chain33/system"
"github.com/33cn/chain33/types"
"github.com/33cn/chain33/util"
...
...
@@ -129,6 +130,8 @@ func TestBlockChain(t *testing.T) {
testReadBlockToExec
(
t
,
blockchain
)
testReExecBlock
(
t
,
blockchain
)
testUpgradeStore
(
t
,
blockchain
)
testProcMainSeqMsg
(
t
,
blockchain
)
}
func
testProcAddBlockMsg
(
t
*
testing
.
T
,
mock33
*
testnode
.
Chain33Mock
,
blockchain
*
blockchain
.
BlockChain
)
{
...
...
@@ -1124,3 +1127,17 @@ func testUpgradeStore(t *testing.T, chain *blockchain.BlockChain) {
chain
.
UpgradeStore
()
chainlog
.
Info
(
"UpgradeStore end ---------------------"
)
}
func
testProcMainSeqMsg
(
t
*
testing
.
T
,
blockchain
*
blockchain
.
BlockChain
)
{
chainlog
.
Info
(
"testProcMainSeqMsg begin -------------------"
)
msg
:=
queue
.
NewMessage
(
1
,
"blockchain"
,
types
.
EventGetLastBlockMainSequence
,
nil
)
blockchain
.
GetLastBlockMainSequence
(
msg
)
assert
.
Equal
(
t
,
int64
(
types
.
EventGetLastBlockMainSequence
),
msg
.
Ty
)
msg
=
queue
.
NewMessage
(
1
,
"blockchain"
,
types
.
EventGetMainSeqByHash
,
&
types
.
ReqHash
{
Hash
:
[]
byte
(
"hash"
)})
blockchain
.
GetMainSeqByHash
(
msg
)
assert
.
Equal
(
t
,
int64
(
types
.
EventGetMainSeqByHash
),
msg
.
Ty
)
chainlog
.
Info
(
"testProcMainSeqMsg end --------------------"
)
}
vendor/github.com/33cn/chain33/blockchain/proc.go
View file @
2b61b2b1
...
...
@@ -70,7 +70,6 @@ func (chain *BlockChain) ProcRecvMsg() {
case
types
.
EventGetBlockByHashes
:
go
chain
.
processMsg
(
msg
,
reqnum
,
chain
.
getBlockByHashes
)
case
types
.
EventGetBlockBySeq
:
go
chain
.
processMsg
(
msg
,
reqnum
,
chain
.
getBlockBySeq
)
...
...
@@ -90,6 +89,12 @@ func (chain *BlockChain) ProcRecvMsg() {
case
types
.
EventGetSeqCBLastNum
:
go
chain
.
processMsg
(
msg
,
reqnum
,
chain
.
getSeqCBLastNum
)
case
types
.
EventGetLastBlockMainSequence
:
go
chain
.
processMsg
(
msg
,
reqnum
,
chain
.
GetLastBlockMainSequence
)
case
types
.
EventGetMainSeqByHash
:
go
chain
.
processMsg
(
msg
,
reqnum
,
chain
.
GetMainSeqByHash
)
default
:
go
chain
.
processMsg
(
msg
,
reqnum
,
chain
.
unknowMsg
)
}
...
...
@@ -519,3 +524,28 @@ func (chain *BlockChain) localAddrTxCount(msg *queue.Message) {
counts
=
count
.
Data
msg
.
Reply
(
chain
.
client
.
NewMessage
(
"rpc"
,
types
.
EventLocalReplyValue
,
&
types
.
Int64
{
Data
:
counts
}))
}
//GetLastBlockMainSequence 获取最新的block执行序列号
func
(
chain
*
BlockChain
)
GetLastBlockMainSequence
(
msg
*
queue
.
Message
)
{
var
lastSequence
types
.
Int64
var
err
error
lastSequence
.
Data
,
err
=
chain
.
blockStore
.
LoadBlockLastMainSequence
()
if
err
!=
nil
{
chainlog
.
Debug
(
"GetLastBlockMainSequence"
,
"err"
,
err
)
msg
.
Reply
(
chain
.
client
.
NewMessage
(
"rpc"
,
types
.
EventReplyLastBlockMainSequence
,
err
))
return
}
msg
.
Reply
(
chain
.
client
.
NewMessage
(
"rpc"
,
types
.
EventReplyLastBlockMainSequence
,
&
lastSequence
))
}
//GetMainSeqByHash parachian 通过blockhash获取对应的seq,只记录了addblock时的seq
func
(
chain
*
BlockChain
)
GetMainSeqByHash
(
msg
*
queue
.
Message
)
{
blockhash
:=
(
msg
.
Data
)
.
(
*
types
.
ReqHash
)
seq
,
err
:=
chain
.
ProcGetMainSeqByHash
(
blockhash
.
Hash
)
if
err
!=
nil
{
chainlog
.
Error
(
"GetMainSeqByHash"
,
"err"
,
err
.
Error
())
msg
.
Reply
(
chain
.
client
.
NewMessage
(
"rpc"
,
types
.
EventReplyMainSeqByHash
,
err
))
return
}
msg
.
Reply
(
chain
.
client
.
NewMessage
(
"rpc"
,
types
.
EventReplyMainSeqByHash
,
&
types
.
Int64
{
Data
:
seq
}))
}
vendor/github.com/33cn/chain33/blockchain/process.go
View file @
2b61b2b1
...
...
@@ -402,7 +402,7 @@ func (b *BlockChain) connectBlock(node *blockNode, blockdetail *types.BlockDetai
}
}
//目前非平行链并开启isRecordBlockSequence功能
if
b
.
isRecordBlockSequence
&&
!
b
.
isParaChain
{
if
b
.
isRecordBlockSequence
{
b
.
pushseq
.
updateSeq
(
lastSequence
)
}
return
blockdetail
,
nil
...
...
@@ -471,7 +471,7 @@ func (b *BlockChain) disconnectBlock(node *blockNode, blockdetail *types.BlockDe
chainlog
.
Debug
(
"disconnectBlock success"
,
"newtipnode.hash"
,
common
.
ToHex
(
newtipnode
.
hash
),
"delblock.parent.hash"
,
common
.
ToHex
(
blockdetail
.
Block
.
GetParentHash
()))
//目前非平行链并开启isRecordBlockSequence功能
if
b
.
isRecordBlockSequence
&&
!
b
.
isParaChain
{
if
b
.
isRecordBlockSequence
{
b
.
pushseq
.
updateSeq
(
lastSequence
)
}
return
nil
...
...
vendor/github.com/33cn/chain33/blockchain/sequences.go
View file @
2b61b2b1
...
...
@@ -90,6 +90,18 @@ func (chain *BlockChain) ProcGetSeqByHash(hash []byte) (int64, error) {
return
seq
,
err
}
//ProcGetMainSeqByHash 处理共识过来的通过blockhash获取seq的消息,只提供add block时的seq,用于平行链block回退
func
(
chain
*
BlockChain
)
ProcGetMainSeqByHash
(
hash
[]
byte
)
(
int64
,
error
)
{
if
len
(
hash
)
==
0
{
chainlog
.
Error
(
"ProcGetMainSeqByHash input hash is null"
)
return
-
1
,
types
.
ErrInvalidParam
}
seq
,
err
:=
chain
.
blockStore
.
GetMainSequenceByHash
(
hash
)
chainlog
.
Debug
(
"ProcGetMainSeqByHash"
,
"blockhash"
,
common
.
ToHex
(
hash
),
"seq"
,
seq
,
"err"
,
err
)
return
seq
,
err
}
//ProcAddBlockSeqCB 添加seq callback
func
(
chain
*
BlockChain
)
ProcAddBlockSeqCB
(
cb
*
types
.
BlockSeqCB
)
error
{
if
cb
==
nil
{
...
...
vendor/github.com/33cn/chain33/client/mock_blockchain_test.go
View file @
2b61b2b1
...
...
@@ -162,6 +162,18 @@ func (m *mockBlockChain) SetQueueClient(q queue.Queue) {
}
else
{
msg
.
ReplyErr
(
"transaction id must 9999"
,
types
.
ErrInvalidParam
)
}
case
types
.
EventGetMainSeqByHash
:
if
req
,
ok
:=
msg
.
GetData
()
.
(
*
types
.
ReqHash
);
ok
&&
string
(
req
.
Hash
)
==
"exist-hash"
{
msg
.
Reply
(
client
.
NewMessage
(
blockchainKey
,
types
.
EventReplyMainSeqByHash
,
&
types
.
Int64
{
Data
:
9999
}))
}
else
{
msg
.
ReplyErr
(
"transaction hash is not exist-hash"
,
types
.
ErrInvalidParam
)
}
case
types
.
EventGetLastBlockMainSequence
:
if
_
,
ok
:=
msg
.
GetData
()
.
(
*
types
.
ReqNil
);
ok
{
msg
.
Reply
(
client
.
NewMessage
(
blockchainKey
,
types
.
EventReplyLastBlockMainSequence
,
&
types
.
Int64
{
Data
:
9999
}))
}
else
{
msg
.
ReplyErr
(
"request must be nil"
,
types
.
ErrInvalidParam
)
}
default
:
msg
.
ReplyErr
(
"Do not support"
,
types
.
ErrNotSupport
)
}
...
...
vendor/github.com/33cn/chain33/client/mocks/api.go
View file @
2b61b2b1
...
...
@@ -361,6 +361,29 @@ func (_m *QueueProtocolAPI) GetHeaders(param *types.ReqBlocks) (*types.Headers,
return
r0
,
r1
}
// GetLastBlockMainSequence provides a mock function with given fields:
func
(
_m
*
QueueProtocolAPI
)
GetLastBlockMainSequence
()
(
*
types
.
Int64
,
error
)
{
ret
:=
_m
.
Called
()
var
r0
*
types
.
Int64
if
rf
,
ok
:=
ret
.
Get
(
0
)
.
(
func
()
*
types
.
Int64
);
ok
{
r0
=
rf
()
}
else
{
if
ret
.
Get
(
0
)
!=
nil
{
r0
=
ret
.
Get
(
0
)
.
(
*
types
.
Int64
)
}
}
var
r1
error
if
rf
,
ok
:=
ret
.
Get
(
1
)
.
(
func
()
error
);
ok
{
r1
=
rf
()
}
else
{
r1
=
ret
.
Error
(
1
)
}
return
r0
,
r1
}
// GetLastBlockSequence provides a mock function with given fields:
func
(
_m
*
QueueProtocolAPI
)
GetLastBlockSequence
()
(
*
types
.
Int64
,
error
)
{
ret
:=
_m
.
Called
()
...
...
@@ -430,6 +453,29 @@ func (_m *QueueProtocolAPI) GetLastMempool() (*types.ReplyTxList, error) {
return
r0
,
r1
}
// GetMainSequenceByHash provides a mock function with given fields: param
func
(
_m
*
QueueProtocolAPI
)
GetMainSequenceByHash
(
param
*
types
.
ReqHash
)
(
*
types
.
Int64
,
error
)
{
ret
:=
_m
.
Called
(
param
)
var
r0
*
types
.
Int64
if
rf
,
ok
:=
ret
.
Get
(
0
)
.
(
func
(
*
types
.
ReqHash
)
*
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
.
ReqHash
)
error
);
ok
{
r1
=
rf
(
param
)
}
else
{
r1
=
ret
.
Error
(
1
)
}
return
r0
,
r1
}
// GetMempool provides a mock function with given fields:
func
(
_m
*
QueueProtocolAPI
)
GetMempool
()
(
*
types
.
ReplyTxList
,
error
)
{
ret
:=
_m
.
Called
()
...
...
vendor/github.com/33cn/chain33/client/queueprotocol.go
View file @
2b61b2b1
...
...
@@ -1139,3 +1139,36 @@ func (q *QueueProtocol) GetSeqCallBackLastNum(param *types.ReqString) (*types.In
}
return
nil
,
types
.
ErrTypeAsset
}
// GetLastBlockMainSequence 获取最新的block执行序列号
func
(
q
*
QueueProtocol
)
GetLastBlockMainSequence
()
(
*
types
.
Int64
,
error
)
{
msg
,
err
:=
q
.
query
(
blockchainKey
,
types
.
EventGetLastBlockMainSequence
,
&
types
.
ReqNil
{})
if
err
!=
nil
{
log
.
Error
(
"GetLastBlockMainSequence"
,
"Error"
,
err
.
Error
())
return
nil
,
err
}
if
reply
,
ok
:=
msg
.
GetData
()
.
(
*
types
.
Int64
);
ok
{
return
reply
,
nil
}
return
nil
,
types
.
ErrTypeAsset
}
// GetMainSequenceByHash 通过hash获取对应的执行序列号
func
(
q
*
QueueProtocol
)
GetMainSequenceByHash
(
param
*
types
.
ReqHash
)
(
*
types
.
Int64
,
error
)
{
if
param
==
nil
{
err
:=
types
.
ErrInvalidParam
log
.
Error
(
"GetMainSequenceByHash"
,
"Error"
,
err
)
return
nil
,
err
}
msg
,
err
:=
q
.
query
(
blockchainKey
,
types
.
EventGetMainSeqByHash
,
param
)
if
err
!=
nil
{
log
.
Error
(
"GetMainSequenceByHash"
,
"Error"
,
err
.
Error
())
return
nil
,
err
}
if
reply
,
ok
:=
msg
.
GetData
()
.
(
*
types
.
Int64
);
ok
{
return
reply
,
nil
}
return
nil
,
types
.
ErrTypeAsset
}
vendor/github.com/33cn/chain33/client/queueprotocol_test.go
View file @
2b61b2b1
...
...
@@ -1196,3 +1196,26 @@ func TestGetBlockBySeq(t *testing.T) {
assert
.
NotNil
(
t
,
err
)
}
func
TestGetMainSeq
(
t
*
testing
.
T
)
{
net
:=
queue
.
New
(
"test-seq-api"
)
defer
net
.
Close
()
chain
:=
&
mockBlockChain
{}
chain
.
SetQueueClient
(
net
)
defer
chain
.
Close
()
api
,
err
:=
client
.
New
(
net
.
Client
(),
nil
)
assert
.
Nil
(
t
,
err
)
seq
,
err
:=
api
.
GetMainSequenceByHash
(
&
types
.
ReqHash
{
Hash
:
[]
byte
(
"exist-hash"
)})
assert
.
Nil
(
t
,
err
)
assert
.
Equal
(
t
,
int64
(
9999
),
seq
.
Data
)
seq
,
err
=
api
.
GetMainSequenceByHash
(
&
types
.
ReqHash
{
Hash
:
[]
byte
(
""
)})
assert
.
NotNil
(
t
,
err
)
seq1
,
err
:=
api
.
GetLastBlockMainSequence
()
assert
.
Nil
(
t
,
err
)
assert
.
Equal
(
t
,
int64
(
9999
),
seq1
.
Data
)
}
vendor/github.com/33cn/chain33/client/queueprotocolapi.go
View file @
2b61b2b1
...
...
@@ -128,6 +128,12 @@ type QueueProtocolAPI interface {
//types.EventGetSequenceByHash:
GetSequenceByHash
(
param
*
types
.
ReqHash
)
(
*
types
.
Int64
,
error
)
// 在平行链上获得主链Sequence相关的接口
//types.EventGetLastBlockSequence:
GetLastBlockMainSequence
()
(
*
types
.
Int64
,
error
)
//types.EventGetSequenceByHash:
GetMainSequenceByHash
(
param
*
types
.
ReqHash
)
(
*
types
.
Int64
,
error
)
// --------------- blockchain interfaces end
// +++++++++++++++ store interfaces begin
...
...
vendor/github.com/33cn/chain33/system/mempool/base.go
View file @
2b61b2b1
...
...
@@ -59,7 +59,7 @@ func NewMempool(cfg *types.Mempool) *Mempool {
pool
.
cfg
=
cfg
pool
.
poolHeader
=
make
(
chan
struct
{},
2
)
pool
.
removeBlockTicket
=
time
.
NewTicker
(
time
.
Minute
)
pool
.
cache
=
newCache
(
cfg
.
MaxTxNumPerAccount
,
cfg
.
MaxTxLast
)
pool
.
cache
=
newCache
(
cfg
.
MaxTxNumPerAccount
,
cfg
.
MaxTxLast
,
cfg
.
PoolCacheSize
)
return
pool
}
...
...
@@ -421,3 +421,26 @@ func (mem *Mempool) setSync(status bool) {
mem
.
sync
=
status
mem
.
proxyMtx
.
Unlock
()
}
// getTxListByHash 从qcache或者SHashTxCache中获取hash对应的tx交易列表
func
(
mem
*
Mempool
)
getTxListByHash
(
hashList
*
types
.
ReqTxHashList
)
*
types
.
ReplyTxList
{
mem
.
proxyMtx
.
Lock
()
defer
mem
.
proxyMtx
.
Unlock
()
var
replyTxList
types
.
ReplyTxList
//通过短hash来获取tx交易
if
hashList
.
GetIsShortHash
()
{
for
_
,
sHash
:=
range
hashList
.
GetHashes
()
{
tx
:=
mem
.
cache
.
GetSHashTxCache
(
sHash
)
replyTxList
.
Txs
=
append
(
replyTxList
.
Txs
,
tx
)
}
return
&
replyTxList
}
//通过hash来获取tx交易
for
_
,
hash
:=
range
hashList
.
GetHashes
()
{
tx
:=
mem
.
cache
.
getTxByHash
(
hash
)
replyTxList
.
Txs
=
append
(
replyTxList
.
Txs
,
tx
)
}
return
&
replyTxList
}
vendor/github.com/33cn/chain33/system/mempool/cache.go
View file @
2b61b2b1
...
...
@@ -34,13 +34,15 @@ type txCache struct {
qcache
QueueCache
totalFee
int64
totalByte
int64
*
SHashTxCache
}
//NewTxCache init accountIndex and last cache
func
newCache
(
maxTxPerAccount
int64
,
sizeLast
int64
)
*
txCache
{
func
newCache
(
maxTxPerAccount
int64
,
sizeLast
int64
,
poolCacheSize
int64
)
*
txCache
{
return
&
txCache
{
AccountTxIndex
:
NewAccountTxIndex
(
int
(
maxTxPerAccount
)),
LastTxCache
:
NewLastTxCache
(
int
(
sizeLast
)),
SHashTxCache
:
NewSHashTxCache
(
int
(
poolCacheSize
)),
}
}
...
...
@@ -64,6 +66,7 @@ func (cache *txCache) Remove(hash string) {
cache
.
LastTxCache
.
Remove
(
tx
)
cache
.
totalFee
-=
tx
.
Fee
cache
.
totalByte
-=
int64
(
proto
.
Size
(
tx
))
cache
.
SHashTxCache
.
Remove
(
tx
)
}
//Exist 是否存在
...
...
@@ -132,6 +135,7 @@ func (cache *txCache) Push(tx *types.Transaction) error {
cache
.
LastTxCache
.
Push
(
tx
)
cache
.
totalFee
+=
tx
.
Fee
cache
.
totalByte
+=
int64
(
proto
.
Size
(
tx
))
cache
.
SHashTxCache
.
Push
(
tx
)
return
nil
}
...
...
@@ -156,3 +160,12 @@ func isExpired(item *Item, height, blockTime int64) bool {
}
return
false
}
//getTxByHash 通过交易hash获取tx交易信息
func
(
cache
*
txCache
)
getTxByHash
(
hash
string
)
*
types
.
Transaction
{
item
,
err
:=
cache
.
qcache
.
GetItem
(
hash
)
if
err
!=
nil
{
return
nil
}
return
item
.
Value
}
vendor/github.com/33cn/chain33/system/mempool/eventprocess.go
View file @
2b61b2b1
...
...
@@ -90,6 +90,9 @@ func (mem *Mempool) eventProcess() {
case
types
.
EventGetProperFee
:
// 获取对应排队策略中合适的手续费
mem
.
eventGetProperFee
(
msg
)
// 消息类型EventTxListByHash:通过hash获取对应的tx列表
case
types
.
EventTxListByHash
:
mem
.
eventTxListByHash
(
msg
)
default
:
}
mlog
.
Debug
(
"mempool"
,
"cost"
,
types
.
Since
(
beg
),
"msg"
,
types
.
GetEventName
(
int
(
msg
.
Ty
)))
...
...
@@ -205,3 +208,10 @@ func (mem *Mempool) checkSign(data *queue.Message) *queue.Message {
data
.
Data
=
types
.
ErrSign
return
data
}
// eventTxListByHash 通过hash获取tx列表
func
(
mem
*
Mempool
)
eventTxListByHash
(
msg
*
queue
.
Message
)
{
shashList
:=
msg
.
GetData
()
.
(
*
types
.
ReqTxHashList
)
replytxList
:=
mem
.
getTxListByHash
(
shashList
)
msg
.
Reply
(
mem
.
client
.
NewMessage
(
""
,
types
.
EventReplyTxList
,
replytxList
))
}
vendor/github.com/33cn/chain33/system/mempool/mempool_test.go
View file @
2b61b2b1
...
...
@@ -1144,3 +1144,94 @@ func execProcess(q queue.Queue) {
}
}()
}
func
TestTx
(
t
*
testing
.
T
)
{
subConfig
:=
SubConfig
{
10240
,
10000
}
cache
:=
newCache
(
10240
,
10
,
10240
)
cache
.
SetQueueCache
(
NewSimpleQueue
(
subConfig
))
tx
:=
&
types
.
Transaction
{
Execer
:
[]
byte
(
"user.write"
),
Payload
:
types
.
Encode
(
transfer
),
Fee
:
100000000
,
Expire
:
0
,
To
:
toAddr
}
var
replyTxList
types
.
ReplyTxList
var
sHastList
types
.
ReqTxHashList
var
hastList
types
.
ReqTxHashList
for
i
:=
1
;
i
<=
10240
;
i
++
{
tx
.
Expire
=
int64
(
i
)
cache
.
Push
(
tx
)
sHastList
.
Hashes
=
append
(
sHastList
.
Hashes
,
types
.
CalcTxShortHash
(
tx
.
Hash
()))
hastList
.
Hashes
=
append
(
hastList
.
Hashes
,
string
(
tx
.
Hash
()))
}
for
i
:=
1
;
i
<=
1600
;
i
++
{
Tx
:=
cache
.
GetSHashTxCache
(
sHastList
.
Hashes
[
i
])
if
Tx
==
nil
{
panic
(
"TestTx:GetSHashTxCache is nil"
)
}
replyTxList
.
Txs
=
append
(
replyTxList
.
Txs
,
Tx
)
}
for
i
:=
1
;
i
<=
1600
;
i
++
{
Tx
:=
cache
.
getTxByHash
(
hastList
.
Hashes
[
i
])
if
Tx
==
nil
{
panic
(
"TestTx:getTxByHash is nil"
)
}
replyTxList
.
Txs
=
append
(
replyTxList
.
Txs
,
Tx
)
}
}
func
TestEventTxListByHash
(
t
*
testing
.
T
)
{
q
,
mem
:=
initEnv
(
0
)
defer
q
.
Close
()
defer
mem
.
Close
()
// add tx
hashes
,
err
:=
add4TxHash
(
mem
.
client
)
if
err
!=
nil
{
t
.
Error
(
"add tx error"
,
err
.
Error
())
return
}
//通过交易hash获取交易信息
reqTxHashList
:=
types
.
ReqTxHashList
{
Hashes
:
hashes
,
IsShortHash
:
false
,
}
msg1
:=
mem
.
client
.
NewMessage
(
"mempool"
,
types
.
EventTxListByHash
,
&
reqTxHashList
)
mem
.
client
.
Send
(
msg1
,
true
)
data1
,
err
:=
mem
.
client
.
Wait
(
msg1
)
if
err
!=
nil
{
t
.
Error
(
err
)
return
}
txs1
:=
data1
.
GetData
()
.
(
*
types
.
ReplyTxList
)
.
GetTxs
()
if
len
(
txs1
)
!=
4
{
t
.
Error
(
"TestEventTxListByHash:get txlist number error"
)
}
for
i
,
tx
:=
range
txs1
{
if
hashes
[
i
]
!=
string
(
tx
.
Hash
())
{
t
.
Error
(
"TestEventTxListByHash:hash mismatch"
)
}
}
//通过短hash获取tx交易
var
shashes
[]
string
for
_
,
hash
:=
range
hashes
{
shashes
=
append
(
shashes
,
types
.
CalcTxShortHash
([]
byte
(
hash
)))
}
reqTxHashList
.
Hashes
=
shashes
reqTxHashList
.
IsShortHash
=
true
msg2
:=
mem
.
client
.
NewMessage
(
"mempool"
,
types
.
EventTxListByHash
,
&
reqTxHashList
)
mem
.
client
.
Send
(
msg2
,
true
)
data2
,
err
:=
mem
.
client
.
Wait
(
msg2
)
if
err
!=
nil
{
t
.
Error
(
err
)
return
}
txs2
:=
data2
.
GetData
()
.
(
*
types
.
ReplyTxList
)
.
GetTxs
()
for
i
,
tx
:=
range
txs2
{
if
hashes
[
i
]
!=
string
(
tx
.
Hash
())
{
t
.
Error
(
"TestEventTxListByHash:shash mismatch"
)
}
}
}
vendor/github.com/33cn/chain33/system/mempool/shorthashtx.go
0 → 100644
View file @
2b61b2b1
package
mempool
import
(
"github.com/33cn/chain33/common"
"github.com/33cn/chain33/common/listmap"
log
"github.com/33cn/chain33/common/log/log15"
"github.com/33cn/chain33/types"
)
var
shashlog
=
log
.
New
(
"module"
,
"mempool.shash"
)
//SHashTxCache 通过shorthash缓存交易
type
SHashTxCache
struct
{
max
int
l
*
listmap
.
ListMap
}
//NewSHashTxCache 创建通过短hash交易的cache
func
NewSHashTxCache
(
size
int
)
*
SHashTxCache
{
return
&
SHashTxCache
{
max
:
size
,
l
:
listmap
.
New
(),
}
}
//GetSHashTxCache 返回shorthash对应的tx交易信息
func
(
cache
*
SHashTxCache
)
GetSHashTxCache
(
sHash
string
)
*
types
.
Transaction
{
tx
,
err
:=
cache
.
l
.
GetItem
(
sHash
)
if
err
!=
nil
{
return
nil
}
return
tx
.
(
*
types
.
Transaction
)
}
//Remove remove tx of SHashTxCache
func
(
cache
*
SHashTxCache
)
Remove
(
tx
*
types
.
Transaction
)
{
txhash
:=
tx
.
Hash
()
cache
.
l
.
Remove
(
types
.
CalcTxShortHash
(
txhash
))
//shashlog.Debug("SHashTxCache:Remove", "shash", types.CalcTxShortHash(txhash), "txhash", common.ToHex(txhash))
}
//Push tx into SHashTxCache
func
(
cache
*
SHashTxCache
)
Push
(
tx
*
types
.
Transaction
)
{
shash
:=
types
.
CalcTxShortHash
(
tx
.
Hash
())
if
cache
.
Exist
(
shash
)
{
shashlog
.
Error
(
"SHashTxCache:Push:Exist"
,
"oldhash"
,
common
.
ToHex
(
cache
.
GetSHashTxCache
(
shash
)
.
Hash
()),
"newhash"
,
common
.
ToHex
(
tx
.
Hash
()))
return
}
if
cache
.
l
.
Size
()
>=
cache
.
max
{
shashlog
.
Error
(
"SHashTxCache:Push:ErrMemFull"
,
"cache.l.Size()"
,
cache
.
l
.
Size
(),
"cache.max"
,
cache
.
max
)
return
}
cache
.
l
.
Push
(
shash
,
tx
)
//shashlog.Debug("SHashTxCache:Push", "shash", shash, "txhash", common.ToHex(tx.Hash()))
}
//Exist 是否存在
func
(
cache
*
SHashTxCache
)
Exist
(
shash
string
)
bool
{
return
cache
.
l
.
Exist
(
shash
)
}
vendor/github.com/33cn/chain33/types/event.go
View file @
2b61b2b1
...
...
@@ -151,11 +151,17 @@ const (
EventGetProperFee
=
140
EventReplyProperFee
=
141
EventReExecBlock
=
142
EventReExecBlock
=
142
EventTxListByHash
=
143
//exec
EventBlockChainQuery
=
212
EventConsensusQuery
=
213
// BlockChain 接收的事件
EventGetLastBlockMainSequence
=
300
EventReplyLastBlockMainSequence
=
301
EventGetMainSeqByHash
=
302
EventReplyMainSeqByHash
=
303
)
var
eventName
=
map
[
int
]
string
{
...
...
@@ -301,4 +307,10 @@ var eventName = map[int]string{
//mempool
EventGetProperFee
:
"EventGetProperFee"
,
EventReplyProperFee
:
"EventReplyProperFee"
,
EventTxListByHash
:
"EventTxListByHash"
,
// block chain
EventGetLastBlockMainSequence
:
"EventGetLastBlockMainSequence"
,
EventReplyLastBlockMainSequence
:
"EventReplyLastBlockMainSequence"
,
EventGetMainSeqByHash
:
"EventGetMainSeqByHash"
,
EventReplyMainSeqByHash
:
"EventReplyMainSeqByHash"
,
}
vendor/github.com/33cn/chain33/types/proto/transaction.proto
View file @
2b61b2b1
...
...
@@ -241,4 +241,10 @@ message UpgradeMeta {
bool
starting
=
1
;
string
version
=
2
;
int64
height
=
3
;
}
\ No newline at end of file
}
//通过交易hash获取交易列表,需要区分是短hash还是全hash值
message
ReqTxHashList
{
repeated
string
hashes
=
1
;
bool
isShortHash
=
2
;
}
vendor/github.com/33cn/chain33/types/transaction.pb.go
View file @
2b61b2b1
...
...
@@ -2016,6 +2016,54 @@ func (m *UpgradeMeta) GetHeight() int64 {
return
0
}
//通过交易hash获取交易列表,需要区分是短hash还是全hash值
type
ReqTxHashList
struct
{
Hashes
[]
string
`protobuf:"bytes,1,rep,name=hashes,proto3" json:"hashes,omitempty"`
IsShortHash
bool
`protobuf:"varint,2,opt,name=isShortHash,proto3" json:"isShortHash,omitempty"`
XXX_NoUnkeyedLiteral
struct
{}
`json:"-"`
XXX_unrecognized
[]
byte
`json:"-"`
XXX_sizecache
int32
`json:"-"`
}
func
(
m
*
ReqTxHashList
)
Reset
()
{
*
m
=
ReqTxHashList
{}
}
func
(
m
*
ReqTxHashList
)
String
()
string
{
return
proto
.
CompactTextString
(
m
)
}
func
(
*
ReqTxHashList
)
ProtoMessage
()
{}
func
(
*
ReqTxHashList
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor_2cc4e03d2c28c490
,
[]
int
{
35
}
}
func
(
m
*
ReqTxHashList
)
XXX_Unmarshal
(
b
[]
byte
)
error
{
return
xxx_messageInfo_ReqTxHashList
.
Unmarshal
(
m
,
b
)
}
func
(
m
*
ReqTxHashList
)
XXX_Marshal
(
b
[]
byte
,
deterministic
bool
)
([]
byte
,
error
)
{
return
xxx_messageInfo_ReqTxHashList
.
Marshal
(
b
,
m
,
deterministic
)
}
func
(
m
*
ReqTxHashList
)
XXX_Merge
(
src
proto
.
Message
)
{
xxx_messageInfo_ReqTxHashList
.
Merge
(
m
,
src
)
}
func
(
m
*
ReqTxHashList
)
XXX_Size
()
int
{
return
xxx_messageInfo_ReqTxHashList
.
Size
(
m
)
}
func
(
m
*
ReqTxHashList
)
XXX_DiscardUnknown
()
{
xxx_messageInfo_ReqTxHashList
.
DiscardUnknown
(
m
)
}
var
xxx_messageInfo_ReqTxHashList
proto
.
InternalMessageInfo
func
(
m
*
ReqTxHashList
)
GetHashes
()
[]
string
{
if
m
!=
nil
{
return
m
.
Hashes
}
return
nil
}
func
(
m
*
ReqTxHashList
)
GetIsShortHash
()
bool
{
if
m
!=
nil
{
return
m
.
IsShortHash
}
return
false
}
func
init
()
{
proto
.
RegisterType
((
*
AssetsGenesis
)(
nil
),
"types.AssetsGenesis"
)
proto
.
RegisterType
((
*
AssetsTransferToExec
)(
nil
),
"types.AssetsTransferToExec"
)
...
...
@@ -2052,93 +2100,96 @@ func init() {
proto
.
RegisterType
((
*
ReqDecodeRawTransaction
)(
nil
),
"types.ReqDecodeRawTransaction"
)
proto
.
RegisterType
((
*
UserWrite
)(
nil
),
"types.UserWrite"
)
proto
.
RegisterType
((
*
UpgradeMeta
)(
nil
),
"types.UpgradeMeta"
)
proto
.
RegisterType
((
*
ReqTxHashList
)(
nil
),
"types.ReqTxHashList"
)
}
func
init
()
{
proto
.
RegisterFile
(
"transaction.proto"
,
fileDescriptor_2cc4e03d2c28c490
)
}
var
fileDescriptor_2cc4e03d2c28c490
=
[]
byte
{
// 1326 bytes of a gzipped FileDescriptorProto
0x1f
,
0x8b
,
0x08
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x02
,
0xff
,
0xc4
,
0x57
,
0xd1
,
0x6e
,
0x1b
,
0xb7
,
0x12
,
0x85
,
0xb4
,
0x5a
,
0x5b
,
0x1a
,
0x29
,
0xb9
,
0xf1
,
0xc2
,
0x48
,
0x84
,
0xe0
,
0xde
,
0xc4
,
0x97
,
0x48
,
0x81
,
0x20
,
0x08
,
0x64
,
0xc0
,
0xce
,
0x5b
,
0x0b
,
0xb4
,
0x49
,
0xdc
,
0x26
,
0x81
,
0x93
,
0x34
,
0x65
,
0x94
,
0xa4
,
0x68
,
0xfb
,
0x42
,
0xaf
,
0xc6
,
0xd2
,
0x36
,
0xd2
,
0x52
,
0xe6
,
0x52
,
0xce
,
0xea
,
0x07
,
0xfa
,
0xd2
,
0xbe
,
0xf5
,
0x93
,
0xfa
,
0x03
,
0xfd
,
0x8c
,
0x7e
,
0x46
,
0xc1
,
0x21
,
0xb9
,
0x4b
,
0x59
,
0x72
,
0x90
,
0x87
,
0x02
,
0x7d
,
0xe3
,
0x21
,
0x47
,
0x33
,
0x67
,
0xce
,
0x0c
,
0x67
,
0x29
,
0xd8
,
0xd1
,
0x4a
,
0xe4
,
0x85
,
0x48
,
0x75
,
0x26
,
0xf3
,
0xc1
,
0x5c
,
0x49
,
0x2d
,
0x93
,
0x58
,
0x2f
,
0xe7
,
0x58
,
0xdc
,
0xec
,
0xa5
,
0x72
,
0x36
,
0xf3
,
0x9b
,
0xec
,
0x05
,
0x5c
,
0x79
,
0x58
,
0x14
,
0xa8
,
0x8b
,
0x27
,
0x98
,
0x63
,
0x91
,
0x15
,
0xc9
,
0x75
,
0xd8
,
0x12
,
0x33
,
0xb9
,
0xc8
,
0x75
,
0xbf
,
0xb9
,
0xd7
,
0xb8
,
0x1b
,
0x71
,
0x87
,
0x92
,
0x3b
,
0x70
,
0x45
,
0xa1
,
0x5e
,
0xa8
,
0xfc
,
0xe1
,
0x68
,
0xa4
,
0xb0
,
0x28
,
0xfa
,
0xd1
,
0x5e
,
0xe3
,
0x6e
,
0x87
,
0xaf
,
0x6e
,
0xb2
,
0xdf
,
0x1a
,
0xb0
,
0x6b
,
0xfd
,
0x0d
,
0x4d
,
0xfc
,
0x53
,
0x54
,
0x43
,
0xf9
,
0x75
,
0x89
,
0x69
,
0xf2
,
0x5f
,
0xe8
,
0xa4
,
0x32
,
0xcb
,
0xb5
,
0x7c
,
0x8f
,
0x79
,
0xbf
,
0x41
,
0x3f
,
0xad
,
0x37
,
0x2e
,
0x0d
,
0x9a
,
0x40
,
0x2b
,
0x97
,
0x1a
,
0x29
,
0x56
,
0x8f
,
0xd3
,
0x3a
,
0xb9
,
0x09
,
0x6d
,
0x2c
,
0x31
,
0x7d
,
0x29
,
0x66
,
0xd8
,
0x6f
,
0x91
,
0xa3
,
0x0a
,
0x27
,
0x57
,
0xa1
,
0xa9
,
0x65
,
0x3f
,
0xa6
,
0xdd
,
0xa6
,
0x96
,
0xec
,
0x97
,
0x06
,
0x5c
,
0xb5
,
0x74
,
0xde
,
0x65
,
0x7a
,
0x32
,
0x52
,
0xe2
,
0xc3
,
0xbf
,
0x44
,
0xe4
,
0x67
,
0xcf
,
0xc3
,
0xcb
,
0xf2
,
0x0f
,
0xf2
,
0xb0
,
0xb1
,
0x5a
,
0x55
,
0xac
,
0x63
,
0x88
,
0x29
,
0x96
,
0x31
,
0x36
,
0x84
,
0x9c
,
0x77
,
0x5a
,
0x1b
,
0xc7
,
0xc5
,
0x72
,
0x76
,
0x22
,
0xa7
,
0xe4
,
0xb8
,
0xc3
,
0x1d
,
0x0a
,
0x02
,
0x46
,
0x61
,
0x40
,
0xf6
,
0x57
,
0x03
,
0xda
,
0x8f
,
0x15
,
0x0a
,
0x8d
,
0xc3
,
0xd2
,
0x45
,
0x6a
,
0xf8
,
0x48
,
0x97
,
0xb2
,
0xbc
,
0x06
,
0xd1
,
0x29
,
0xa2
,
0xf3
,
0x64
,
0x96
,
0x15
,
0xef
,
0x56
,
0xc0
,
0xfb
,
0x16
,
0x40
,
0x56
,
0xd5
,
0x85
,
0xb4
,
0x6a
,
0xf3
,
0x60
,
0x27
,
0xe9
,
0xc3
,
0x76
,
0x56
,
0x0c
,
0x49
,
0x9f
,
0x2d
,
0x3a
,
0xf4
,
0x30
,
0xd9
,
0x83
,
0x2e
,
0xc9
,
0xf4
,
0xda
,
0x66
,
0xb2
,
0x4d
,
0x84
,
0xc2
,
0xad
,
0x95
,
0xda
,
0xb4
,
0x2f
,
0xd4
,
0xe6
,
0x3a
,
0x6c
,
0x99
,
0x35
,
0xaa
,
0x7e
,
0xc7
,
0x4a
,
0x60
,
0x11
,
0xcb
,
0xa1
,
0xc7
,
0xf1
,
0x9d
,
0xca
,
0x34
,
0x72
,
0xf1
,
0xc1
,
0x65
,
0x5b
,
0x56
,
0xd9
,
0xfa
,
0xec
,
0xa3
,
0x30
,
0x7b
,
0x2c
,
0xe7
,
0x99
,
0xf2
,
0xd5
,
0x77
,
0xc8
,
0x67
,
0x1f
,
0xd7
,
0xd9
,
0xef
,
0x42
,
0x9c
,
0xe5
,
0x23
,
0x2c
,
0x29
,
0x8f
,
0x98
,
0x5b
,
0xc0
,
0xee
,
0xc1
,
0x75
,
0xa7
,
0x6c
,
0x7d
,
0x55
,
0x9f
,
0x28
,
0xb9
,
0x98
,
0x1b
,
0x0f
,
0xba
,
0x2c
,
0xfa
,
0x8d
,
0xbd
,
0xe8
,
0x6e
,
0x87
,
0x9b
,
0x25
,
0xbb
,
0x05
,
0xed
,
0x37
,
0x79
,
0x91
,
0x8d
,
0xf3
,
0x61
,
0x69
,
0xb4
,
0x1c
,
0x09
,
0x2d
,
0x88
,
0x59
,
0x8f
,
0xd3
,
0x9a
,
0x49
,
0xe8
,
0xbe
,
0x94
,
0x8f
,
0xc4
,
0x54
,
0xe4
,
0xa9
,
0x29
,
0xd4
,
0x2e
,
0xc4
,
0xba
,
0x7c
,
0x8a
,
0x9e
,
0xbd
,
0x05
,
0x46
,
0xd0
,
0xb9
,
0x58
,
0x9a
,
0xab
,
0xea
,
0x8a
,
0xef
,
0x21
,
0x9d
,
0xa8
,
0xec
,
0xfc
,
0x3d
,
0x2e
,
0x5d
,
0x7e
,
0x1e
,
0x5e
,
0x96
,
0x24
,
0xfb
,
0xb5
,
0x09
,
0xdd
,
0x80
,
0x77
,
0x20
,
0xaa
,
0xa5
,
0xe5
,
0x90
,
0x8b
,
0x39
,
0x95
,
0x62
,
0x44
,
0x31
,
0x7b
,
0xdc
,
0xc3
,
0x64
,
0x00
,
0x1d
,
0x93
,
0x90
,
0xd0
,
0x0b
,
0x65
,
0x5b
,
0xa5
,
0x7b
,
0x70
,
0x6d
,
0x40
,
0x23
,
0x6a
,
0xf0
,
0xda
,
0xef
,
0xf3
,
0xda
,
0xc4
,
0xcb
,
0xda
,
0xaa
,
0x65
,
0xad
,
0xb9
,
0x59
,
0xad
,
0x7d
,
0x01
,
0x76
,
0x21
,
0xce
,
0x65
,
0x9e
,
0x22
,
0xc9
,
0x1d
,
0x71
,
0x0b
,
0x5c
,
0xf9
,
0xb6
,
0xab
,
0xf2
,
0xdd
,
0x02
,
0x18
,
0x1b
,
0xb5
,
0x1f
,
0x53
,
0x03
,
0xb7
,
0xa9
,
0x32
,
0xc1
,
0x8e
,
0xf1
,
0x3e
,
0x41
,
0x31
,
0x72
,
0x6d
,
0xd2
,
0xe3
,
0x0e
,
0x51
,
0x2b
,
0x63
,
0xa9
,
0xfb
,
0xe0
,
0x5a
,
0x19
,
0x4b
,
0xcd
,
0x1e
,
0x40
,
0x2f
,
0x10
,
0xa3
,
0x48
,
0xee
,
0xd4
,
0x05
,
0xec
,
0x1e
,
0x24
,
0x2e
,
0xab
,
0xc0
,
0xc2
,
0x16
,
0xf5
,
0x4b
,
0xb8
,
0xc2
,
0xb3
,
0x7c
,
0x5c
,
0x65
,
0x9b
,
0x0c
,
0x20
,
0xce
,
0x34
,
0xce
,
0xfc
,
0x0f
,
0xfb
,
0xee
,
0x87
,
0x2b
,
0x46
,
0xcf
,
0x34
,
0xce
,
0xb8
,
0x35
,
0x63
,
0xcf
,
0x60
,
0x67
,
0xed
,
0xcc
,
0xf0
,
0x9e
,
0x2f
,
0x4e
,
0x4c
,
0x29
,
0x8d
,
0x97
,
0x1e
,
0x77
,
0xc8
,
0x0c
,
0x9c
,
0x5a
,
0xef
,
0x26
,
0x1d
,
0xd5
,
0x1b
,
0xec
,
0x3b
,
0xe8
,
0xd4
,
0x3c
,
0x8c
,
0x54
,
0x4b
,
0x2a
,
0x64
,
0xcc
,
0x9b
,
0x7a
,
0x19
,
0xb8
,
0xb4
,
0x35
,
0xdc
,
0xe8
,
0xd2
,
0x8e
,
0xa4
,
0xc0
,
0xe5
,
0x4f
,
0xd0
,
0x33
,
0xcd
,
0xf5
,
0xed
,
0x39
,
0xaa
,
0xf3
,
0x0c
,
0xe9
,
0x3e
,
0x2b
,
0x4c
,
0xb3
,
0x73
,
0xd7
,
0x23
,
0x11
,
0xf7
,
0xd0
,
0x9c
,
0x9c
,
0xd8
,
0xde
,
0x75
,
0x83
,
0xc4
,
0x43
,
0x73
,
0xa2
,
0xcb
,
0xc7
,
0xc1
,
0x5c
,
0xf2
,
0x90
,
0xfd
,
0xde
,
0x80
,
0x6d
,
0x8e
,
0x67
,
0xd4
,
0xbe
,
0x09
,
0xb4
,
0x84
,
0xe9
,
0x6a
,
0x37
,
0xe8
,
0x84
,
0xdb
,
0x3b
,
0x9d
,
0x8a
,
0x31
,
0x39
,
0x8c
,
0x39
,
0xad
,
0x4d
,
0x63
,
0xa4
,
0x95
,
0xaf
,
0x98
,
0x5b
,
0x60
,
0xb2
,
0x18
,
0x65
,
0x0a
,
0xa9
,
0x30
,
0xd4
,
0x5e
,
0x31
,
0xaf
,
0x37
,
0x6c
,
0x1b
,
0x64
,
0xe3
,
0x89
,
0xf6
,
0x4d
,
0x66
,
0xd1
,
0xea
,
0x9d
,
0x8e
,
0xfc
,
0x9d
,
0xfe
,
0x1e
,
0x80
,
0xe3
,
0xd9
,
0x2b
,
0x95
,
0x9d
,
0x8b
,
0x74
,
0x59
,
0xc7
,
0x6b
,
0x5c
,
0x1a
,
0xaf
,
0x79
,
0x79
,
0xbc
,
0x28
,
0x8c
,
0xc7
,
0x6e
,
0x40
,
0xfc
,
0x14
,
0xcb
,
0xf5
,
0xb1
,
0xc4
,
0x16
,
0xd0
,
0xe5
,
0x38
,
0x9f
,
0x2e
,
0x87
,
0xe5
,
0xb3
,
0xfc
,
0x54
,
0x9a
,
0xbc
,
0x27
,
0xa2
,
0x98
,
0xf8
,
0xe9
,
0x60
,
0xd6
,
0x81
,
0xcf
,
0xe6
,
0xe6
,
0x1c
,
0xa2
,
0x20
,
0x87
,
0xe4
,
0x0e
,
0x6c
,
0x09
,
0xfa
,
0x56
,
0xf5
,
0x5b
,
0xd4
,
0x86
,
0x3d
,
0xd7
,
0x86
,
0xf4
,
0x51
,
0xe1
,
0xee
,
0x8c
,
0xfd
,
0x1f
,
0x3a
,
0x1c
,
0xcf
,
0x86
,
0xe5
,
0xf3
,
0xac
,
0xd0
,
0xab
,
0x89
,
0x46
,
0x2e
,
0x51
,
0x76
,
0x58
,
0x31
,
0x23
,
0xa3
,
0x4f
,
0xbb
,
0x14
,
0x03
,
0xb8
,
0x4a
,
0x3f
,
0x7a
,
0xa5
,
0xe4
,
0x1c
,
0xd5
,
0x37
,
0x88
,
0x46
,
0xaf
,
0xb9
,
0x07
,
0x2e
,
0x40
,
0xbd
,
0xc1
,
0x38
,
0xc0
,
0xb0
,
0x7c
,
0x2a
,
0x8a
,
0x09
,
0xc5
,
0x30
,
0x99
,
0x8a
,
0x62
,
0x82
,
0x85
,
0x6f
,
0x7e
,
0x8b
,
0x6a
,
0x82
,
0xcd
,
0x80
,
0x60
,
0x30
,
0x40
,
0xa2
,
0xbd
,
0xa8
,
0x1e
,
0x20
,
0xec
,
0x0b
,
0xf3
,
0x25
,
0xa8
,
0x24
,
0x2d
,
0x92
,
0xfb
,
0xa6
,
0x0b
,
0x69
,
0x79
,
0x81
,
0x7d
,
0x60
,
0xc5
,
0xbd
,
0x09
,
0x1b
,
0x98
,
0x1e
,
0x48
,
0x31
,
0x9b
,
0xeb
,
0xe7
,
0x72
,
0xbc
,
0x76
,
0x97
,
0xae
,
0x41
,
0x34
,
0x95
,
0x63
,
0x77
,
0x91
,
0xcc
,
0x92
,
0x09
,
0xd3
,
0xc8
,
0x64
,
0xbf
,
0x66
,
0x7c
,
0x1b
,
0x9a
,
0xc7
,
0x6f
,
0xe9
,
0xb2
,
0x76
,
0x0f
,
0xfe
,
0xe3
,
0x62
,
0x1e
,
0xe3
,
0xf2
,
0xad
,
0x98
,
0x2e
,
0x90
,
0x37
,
0x8f
,
0xdf
,
0x26
,
0x9f
,
0x41
,
0x6b
,
0x2a
,
0xc7
,
0x05
,
0xf1
,
0xef
,
0x1e
,
0xec
,
0x54
,
0xb4
,
0x7c
,
0x78
,
0x4e
,
0xc7
,
0xec
,
0xc8
,
0x54
,
0x82
,
0xf6
,
0x8e
,
0x84
,
0x16
,
0x6b
,
0x61
,
0x3e
,
0xd1
,
0xcb
,
0x9f
,
0x0d
,
0x68
,
0x0f
,
0x4b
,
0x8e
,
0xc5
,
0x62
,
0xaa
,
0x83
,
0x9e
,
0x6a
,
0x6c
,
0xee
,
0xa9
,
0x66
,
0xf0
,
0xad
,
0x4b
,
0x18
,
0x35
,
0xad
,
0x9d
,
0xf2
,
0x9b
,
0x4a
,
0x6f
,
0xbe
,
0xaf
,
0x0f
,
0xa0
,
0xab
,
0x6c
,
0xc8
,
0x91
,
0x70
,
0x4f
,
0x85
,
0x50
,
0xe9
,
0x8a
,
0x3e
,
0x0f
,
0xcd
,
0x4c
,
0x77
,
0x9c
,
0x4c
,
0x65
,
0xfa
,
0x5e
,
0x67
,
0x33
,
0xff
,
0x1d
,
0xa8
,
0x37
,
0xcc
,
0x90
,
0xb7
,
0x11
,
0xe8
,
0x25
,
0xb0
,
0x45
,
0x97
,
0x26
,
0xd8
,
0x61
,
0x7f
,
0x34
,
0x61
,
0x27
,
0xe0
,
0x71
,
0x84
,
0x5a
,
0x64
,
0x53
,
0xc7
,
0xb6
,
0xf1
,
0x51
,
0xb6
,
0xf7
,
0x69
,
0x9a
,
0x19
,
0x1a
,
0x94
,
0xe9
,
0x66
,
0xa6
,
0xde
,
0x84
,
0x26
,
0xa8
,
0x92
,
0xf2
,
0xd4
,
0x6a
,
0x6c
,
0x26
,
0x28
,
0xa1
,
0x40
,
0xc5
,
0xd6
,
0x66
,
0x15
,
0xe3
,
0xf0
,
0x66
,
0xae
,
0xe4
,
0xba
,
0x75
,
0x31
,
0xd7
,
0xfa
,
0x35
,
0xb6
,
0xbd
,
0xf2
,
0x1a
,
0xbb
,
0x09
,
0xed
,
0x53
,
0x25
,
0x67
,
0x34
,
0x21
,
0xdd
,
0x5b
,
0xc8
,
0xe3
,
0x0b
,
0xfa
,
0x74
,
0x2e
,
0xea
,
0x13
,
0xcc
,
0x02
,
0xf8
,
0xc8
,
0x2c
,
0xf8
,
0x0a
,
0x92
,
0x35
,
0x11
,
0x8b
,
0xe4
,
0x5e
,
0x78
,
0xdf
,
0xfb
,
0xeb
,
0x32
,
0x5a
,
0x3b
,
0x7b
,
0xeb
,
0xf7
,
0xa0
,
0xed
,
0x86
,
0x39
,
0xdd
,
0x55
,
0xc3
,
0xcd
,
0xbf
,
0x7f
,
0x2c
,
0x60
,
0xfb
,
0x70
,
0x83
,
0xe3
,
0xd9
,
0x11
,
0xa6
,
0x72
,
0x44
,
0xef
,
0xb3
,
0xe0
,
0xed
,
0xb1
,
0xf1
,
0xb5
,
0xc3
,
0x3e
,
0x87
,
0xce
,
0x9b
,
0x02
,
0x15
,
0x3d
,
0xe8
,
0xc8
,
0x44
,
0xce
,
0xb3
,
0xb4
,
0x32
,
0x31
,
0xc0
,
0x7c
,
0x5d
,
0x52
,
0x99
,
0x6b
,
0x74
,
0x73
,
0xa1
,
0xc3
,
0x3d
,
0x64
,
0x3f
,
0x42
,
0xf7
,
0xcd
,
0x7c
,
0xac
,
0xc4
,
0x08
,
0x5f
,
0xa0
,
0x16
,
0x46
,
0xc2
,
0x42
,
0x0b
,
0xa5
,
0xb3
,
0x7c
,
0x4c
,
0x1e
,
0xda
,
0xbc
,
0xc2
,
0xc6
,
0xc9
,
0x39
,
0xaa
,
0xc2
,
0x0f
,
0xf3
,
0x0e
,
0xf7
,
0xf0
,
0xb2
,
0x51
,
0xfe
,
0xe8
,
0xf6
,
0x0f
,
0xff
,
0x1b
,
0x67
,
0x7a
,
0xb2
,
0x38
,
0x19
,
0xa4
,
0x72
,
0xb6
,
0x7f
,
0x78
,
0x98
,
0xe6
,
0xfb
,
0xe9
,
0x44
,
0x64
,
0xf9
,
0xe1
,
0xe1
,
0x3e
,
0x89
,
0x74
,
0xb2
,
0x45
,
0xff
,
0xcd
,
0x0e
,
0xff
,
0x0e
,
0x00
,
0x00
,
0xff
,
0xff
,
0x05
,
0xe5
,
0x01
,
0x1a
,
0xc5
,
0x0d
,
0x00
,
0x00
,
// 1351 bytes of a gzipped FileDescriptorProto
0x1f
,
0x8b
,
0x08
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x02
,
0xff
,
0xc4
,
0x57
,
0xdd
,
0x8e
,
0x13
,
0xc7
,
0x12
,
0x96
,
0x3d
,
0x1e
,
0xaf
,
0x5d
,
0xf6
,
0x72
,
0xd8
,
0xd1
,
0x0a
,
0x2c
,
0x74
,
0x0e
,
0xf8
,
0x8c
,
0x88
,
0x84
,
0x10
,
0xf2
,
0x4a
,
0xbb
,
0xdc
,
0x25
,
0x52
,
0x02
,
0x6c
,
0x02
,
0xab
,
0x05
,
0x42
,
0x1a
,
0x03
,
0x51
,
0x92
,
0x9b
,
0xde
,
0x71
,
0xad
,
0x3d
,
0xc1
,
0x9e
,
0xf6
,
0xf6
,
0xb4
,
0x97
,
0xf1
,
0x0b
,
0xe4
,
0x26
,
0xb9
,
0xcb
,
0x23
,
0xe5
,
0x05
,
0xf2
,
0x18
,
0x79
,
0x8c
,
0xa8
,
0xab
,
0xbb
,
0x67
,
0xda
,
0x6b
,
0x1b
,
0x71
,
0x11
,
0x29
,
0x77
,
0x5d
,
0xd5
,
0xe5
,
0xaa
,
0xaf
,
0xbe
,
0xfa
,
0x99
,
0x36
,
0xec
,
0x29
,
0xc9
,
0xb3
,
0x9c
,
0x27
,
0x2a
,
0x15
,
0xd9
,
0x60
,
0x2e
,
0x85
,
0x12
,
0x51
,
0xa8
,
0x96
,
0x73
,
0xcc
,
0x6f
,
0x75
,
0x13
,
0x31
,
0x9b
,
0x39
,
0x65
,
0xfc
,
0x02
,
0x76
,
0x1f
,
0xe5
,
0x39
,
0xaa
,
0xfc
,
0x29
,
0x66
,
0x98
,
0xa7
,
0x79
,
0x74
,
0x03
,
0x9a
,
0x7c
,
0x26
,
0x16
,
0x99
,
0xea
,
0xd5
,
0xfb
,
0xb5
,
0x7b
,
0x01
,
0xb3
,
0x52
,
0x74
,
0x17
,
0x76
,
0x25
,
0xaa
,
0x85
,
0xcc
,
0x1e
,
0x8d
,
0x46
,
0x12
,
0xf3
,
0xbc
,
0x17
,
0xf4
,
0x6b
,
0xf7
,
0xda
,
0x6c
,
0x55
,
0x19
,
0xff
,
0x56
,
0x83
,
0x7d
,
0xe3
,
0x6f
,
0xa8
,
0xe3
,
0x9f
,
0xa3
,
0x1c
,
0x8a
,
0xaf
,
0x0b
,
0x4c
,
0xa2
,
0xff
,
0x42
,
0x3b
,
0x11
,
0x69
,
0xa6
,
0xc4
,
0x7b
,
0xcc
,
0x7a
,
0x35
,
0xfa
,
0x69
,
0xa5
,
0xd8
,
0x1a
,
0x34
,
0x82
,
0x46
,
0x26
,
0x14
,
0x52
,
0xac
,
0x2e
,
0xa3
,
0x73
,
0x74
,
0x0b
,
0x5a
,
0x58
,
0x60
,
0xf2
,
0x92
,
0xcf
,
0xb0
,
0xd7
,
0x20
,
0x47
,
0xa5
,
0x1c
,
0x5d
,
0x83
,
0xba
,
0x12
,
0xbd
,
0x90
,
0xb4
,
0x75
,
0x25
,
0xe2
,
0x5f
,
0x6a
,
0x70
,
0xcd
,
0xc0
,
0x79
,
0x97
,
0xaa
,
0xc9
,
0x48
,
0xf2
,
0x0f
,
0xff
,
0x12
,
0x90
,
0x9f
,
0x1d
,
0x0e
,
0x47
,
0xcb
,
0x3f
,
0x88
,
0xc3
,
0xc4
,
0x6a
,
0x94
,
0xb1
,
0x4e
,
0x21
,
0xa4
,
0x58
,
0xda
,
0x58
,
0x03
,
0xb2
,
0xde
,
0xe9
,
0xac
,
0x1d
,
0xe7
,
0xcb
,
0xd9
,
0x99
,
0x98
,
0x92
,
0xe3
,
0x36
,
0xb3
,
0x92
,
0x17
,
0x30
,
0xf0
,
0x03
,
0xc6
,
0x7f
,
0xd5
,
0xa0
,
0xf5
,
0x44
,
0x22
,
0x57
,
0x38
,
0x2c
,
0x6c
,
0xa4
,
0x9a
,
0x8b
,
0xb4
,
0x15
,
0xe5
,
0x75
,
0x08
,
0xce
,
0x11
,
0xad
,
0x27
,
0x7d
,
0x2c
,
0x71
,
0x37
,
0x3c
,
0xdc
,
0xb7
,
0x01
,
0xd2
,
0xb2
,
0x2e
,
0xc4
,
0x55
,
0x8b
,
0x79
,
0x9a
,
0xa8
,
0x07
,
0x3b
,
0x69
,
0x3e
,
0x24
,
0x7e
,
0x9a
,
0x74
,
0xe9
,
0xc4
,
0xa8
,
0x0f
,
0x1d
,
0xa2
,
0xe9
,
0xb5
,
0xc9
,
0x64
,
0x87
,
0x00
,
0xf9
,
0xaa
,
0x95
,
0xda
,
0xb4
,
0xae
,
0xd4
,
0xe6
,
0x06
,
0x34
,
0xf5
,
0x19
,
0x65
,
0xaf
,
0x6d
,
0x28
,
0x30
,
0x52
,
0x9c
,
0x41
,
0x97
,
0xe1
,
0x3b
,
0x99
,
0x2a
,
0x64
,
0xfc
,
0x83
,
0xcd
,
0xb6
,
0x28
,
0xb3
,
0x75
,
0xd9
,
0x07
,
0x7e
,
0xf6
,
0x58
,
0xcc
,
0x53
,
0xe9
,
0xaa
,
0x6f
,
0x25
,
0x97
,
0x7d
,
0x58
,
0x65
,
0xbf
,
0x0f
,
0x61
,
0x9a
,
0x8d
,
0xb0
,
0xa0
,
0x3c
,
0x42
,
0x66
,
0x84
,
0xf8
,
0x3e
,
0xdc
,
0xb0
,
0xcc
,
0x56
,
0xa3
,
0xfa
,
0x54
,
0x8a
,
0xc5
,
0x5c
,
0x7b
,
0x50
,
0x45
,
0xde
,
0xab
,
0xf5
,
0x83
,
0x7b
,
0x6d
,
0xa6
,
0x8f
,
0xf1
,
0x6d
,
0x68
,
0xbd
,
0xc9
,
0xf2
,
0x74
,
0x9c
,
0x0d
,
0x0b
,
0xcd
,
0xe5
,
0x88
,
0x2b
,
0x4e
,
0xc8
,
0xba
,
0x8c
,
0xce
,
0xb1
,
0x80
,
0xce
,
0x4b
,
0xf1
,
0x98
,
0x4f
,
0x79
,
0x96
,
0xe8
,
0x42
,
0xed
,
0x43
,
0xa8
,
0x8a
,
0x67
,
0xe8
,
0xd0
,
0x1b
,
0x41
,
0x13
,
0x3a
,
0xe7
,
0x4b
,
0x3d
,
0xaa
,
0xb6
,
0xf8
,
0x4e
,
0xa4
,
0x1b
,
0x99
,
0x5e
,
0xbe
,
0xc7
,
0xa5
,
0xcd
,
0xcf
,
0x89
,
0xdb
,
0x92
,
0x8c
,
0x7f
,
0xad
,
0x43
,
0xc7
,
0xc3
,
0xed
,
0x91
,
0x6a
,
0x60
,
0x59
,
0xc9
,
0xc6
,
0x9c
,
0x0a
,
0x3e
,
0xa2
,
0x98
,
0x5d
,
0xe6
,
0xc4
,
0x68
,
0x00
,
0x6d
,
0x9d
,
0x10
,
0x57
,
0x0b
,
0x69
,
0x5a
,
0xa5
,
0x73
,
0x78
,
0x7d
,
0x40
,
0x2b
,
0x6a
,
0xf0
,
0xda
,
0xe9
,
0x59
,
0x65
,
0xe2
,
0x68
,
0x6d
,
0x54
,
0xb4
,
0x56
,
0xd8
,
0x0c
,
0xd7
,
0xae
,
0x00
,
0xfb
,
0x10
,
0x66
,
0x22
,
0x4b
,
0x90
,
0xe8
,
0x0e
,
0x98
,
0x11
,
0x6c
,
0xf9
,
0x76
,
0xca
,
0xf2
,
0xdd
,
0x06
,
0x18
,
0x6b
,
0xb6
,
0x9f
,
0x50
,
0x03
,
0xb7
,
0xa8
,
0x32
,
0x9e
,
0x46
,
0x7b
,
0x9f
,
0x20
,
0x1f
,
0xd9
,
0x36
,
0xe9
,
0x32
,
0x2b
,
0x51
,
0x2b
,
0x63
,
0xa1
,
0x7a
,
0x60
,
0x5b
,
0x19
,
0x0b
,
0x15
,
0x3f
,
0x84
,
0xae
,
0x47
,
0x46
,
0x1e
,
0xdd
,
0xad
,
0x0a
,
0xd8
,
0x39
,
0x8c
,
0x6c
,
0x56
,
0x9e
,
0x85
,
0x29
,
0xea
,
0x97
,
0xb0
,
0xcb
,
0xd2
,
0x6c
,
0x5c
,
0x66
,
0x1b
,
0x0d
,
0x20
,
0x4c
,
0x15
,
0xce
,
0xdc
,
0x0f
,
0x7b
,
0xf6
,
0x87
,
0x2b
,
0x46
,
0x27
,
0x0a
,
0x67
,
0xcc
,
0x98
,
0xc5
,
0x27
,
0xb0
,
0xb7
,
0x76
,
0xa7
,
0x71
,
0xcf
,
0x17
,
0x67
,
0xba
,
0x94
,
0xda
,
0x4b
,
0x97
,
0x59
,
0x49
,
0x2f
,
0x9c
,
0x8a
,
0xef
,
0x3a
,
0x5d
,
0x55
,
0x8a
,
0xf8
,
0x3b
,
0x68
,
0x57
,
0x38
,
0x34
,
0x55
,
0x4b
,
0x2a
,
0x64
,
0xc8
,
0xea
,
0x6a
,
0xe9
,
0xb9
,
0x34
,
0x35
,
0xdc
,
0xe8
,
0xd2
,
0xac
,
0x24
,
0xcf
,
0xe5
,
0x4f
,
0xd0
,
0xd5
,
0xcd
,
0xf5
,
0xed
,
0x25
,
0xca
,
0xcb
,
0x14
,
0x69
,
0x9e
,
0x25
,
0x26
,
0xe9
,
0xa5
,
0xed
,
0x91
,
0x80
,
0x39
,
0x51
,
0xdf
,
0x9c
,
0x99
,
0xde
,
0xb5
,
0x8b
,
0xc4
,
0x89
,
0xfa
,
0x46
,
0x15
,
0x4f
,
0xbc
,
0xbd
,
0xe4
,
0xc4
,
0xf8
,
0xf7
,
0x1a
,
0xec
,
0x30
,
0xbc
,
0xa0
,
0xf6
,
0x8d
,
0xa0
,
0xc1
,
0x75
,
0x57
,
0xdb
,
0x45
,
0xc7
,
0xad
,
0xee
,
0x7c
,
0xca
,
0xc7
,
0xe4
,
0x30
,
0x64
,
0x74
,
0xd6
,
0x8d
,
0x91
,
0x94
,
0xbe
,
0x42
,
0x66
,
0x04
,
0x9d
,
0xc5
,
0x28
,
0x95
,
0x48
,
0x85
,
0xa1
,
0xf6
,
0x0a
,
0x59
,
0xa5
,
0x30
,
0x6d
,
0x90
,
0x8e
,
0x27
,
0xca
,
0x35
,
0x99
,
0x91
,
0x56
,
0x67
,
0x3a
,
0x70
,
0x33
,
0xfd
,
0x3d
,
0x00
,
0xc3
,
0x8b
,
0x57
,
0x32
,
0xbd
,
0xe4
,
0xc9
,
0xb2
,
0x8a
,
0x57
,
0xdb
,
0x1a
,
0xaf
,
0xbe
,
0x3d
,
0x5e
,
0xe0
,
0xc7
,
0x8b
,
0x6f
,
0x42
,
0xf8
,
0x0c
,
0x8b
,
0xf5
,
0xb5
,
0x14
,
0x2f
,
0xa0
,
0xc3
,
0x70
,
0x3e
,
0x5d
,
0x0e
,
0x8b
,
0x93
,
0xec
,
0x5c
,
0xe8
,
0xbc
,
0x27
,
0x3c
,
0x9f
,
0xb8
,
0xed
,
0xa0
,
0xcf
,
0x9e
,
0xcf
,
0xfa
,
0xe6
,
0x1c
,
0x02
,
0x2f
,
0x87
,
0xe8
,
0x2e
,
0x34
,
0x39
,
0x7d
,
0xab
,
0x7a
,
0x0d
,
0x6a
,
0xc3
,
0xae
,
0x6d
,
0x43
,
0xfa
,
0xa8
,
0x30
,
0x7b
,
0x17
,
0xff
,
0x1f
,
0xda
,
0x0c
,
0x2f
,
0x86
,
0xc5
,
0xf3
,
0x34
,
0x57
,
0xab
,
0x89
,
0x06
,
0x36
,
0xd1
,
0xf8
,
0xa8
,
0x44
,
0x46
,
0x46
,
0x9f
,
0x36
,
0x14
,
0x03
,
0xb8
,
0x46
,
0x3f
,
0x7a
,
0x25
,
0xc5
,
0x1c
,
0xe5
,
0x37
,
0x88
,
0x9a
,
0xaf
,
0xb9
,
0x13
,
0x6c
,
0x80
,
0x4a
,
0x11
,
0x33
,
0x80
,
0x61
,
0xf1
,
0x8c
,
0xe7
,
0x13
,
0x8a
,
0xa1
,
0x33
,
0xe5
,
0xf9
,
0x04
,
0x73
,
0xd7
,
0xfc
,
0x46
,
0xaa
,
0x00
,
0xd6
,
0x3d
,
0x80
,
0xde
,
0x02
,
0x09
,
0xfa
,
0x41
,
0xb5
,
0x40
,
0xe2
,
0x2f
,
0xf4
,
0x97
,
0xa0
,
0xa4
,
0x34
,
0x8f
,
0x1e
,
0xe8
,
0x2e
,
0xa4
,
0xe3
,
0x15
,
0xf4
,
0x9e
,
0x15
,
0x73
,
0x26
,
0xf1
,
0x40
,
0xf7
,
0x40
,
0x82
,
0xe9
,
0x5c
,
0x3d
,
0x17
,
0xe3
,
0xb5
,
0x59
,
0xba
,
0x0e
,
0xc1
,
0x54
,
0x8c
,
0xed
,
0x20
,
0xe9
,
0x63
,
0xcc
,
0x75
,
0x23
,
0x93
,
0xfd
,
0x9a
,
0xf1
,
0x1d
,
0xa8
,
0x9f
,
0xbe
,
0xa5
,
0x61
,
0xed
,
0x1c
,
0xfe
,
0xc7
,
0xc6
,
0x3c
,
0xc5
,
0xe5
,
0x5b
,
0x3e
,
0x5d
,
0x20
,
0xab
,
0x9f
,
0xbe
,
0x8d
,
0x3e
,
0x83
,
0xc6
,
0x54
,
0x8c
,
0x73
,
0xc2
,
0xdf
,
0x39
,
0xdc
,
0x2b
,
0x61
,
0xb9
,
0xf0
,
0x8c
,
0xae
,
0xe3
,
0x63
,
0x5d
,
0x09
,
0xd2
,
0x1d
,
0x73
,
0xc5
,
0xd7
,
0xc2
,
0x7c
,
0xa2
,
0x97
,
0x3f
,
0x6b
,
0xd0
,
0x1a
,
0x16
,
0x0c
,
0xf3
,
0xc5
,
0x54
,
0x79
,
0x3d
,
0x55
,
0xdb
,
0xdc
,
0x53
,
0x75
,
0xef
,
0x5b
,
0x17
,
0xc5
,
0xd4
,
0xb4
,
0x66
,
0xcb
,
0x6f
,
0x2a
,
0xbd
,
0xfe
,
0xbe
,
0x3e
,
0x84
,
0x8e
,
0x34
,
0x21
,
0x47
,
0xdc
,
0x3e
,
0x15
,
0x7c
,
0xa6
,
0x4b
,
0xf8
,
0xcc
,
0x37
,
0xd3
,
0xdd
,
0x71
,
0x36
,
0x15
,
0xc9
,
0x7b
,
0x95
,
0xce
,
0xdc
,
0x77
,
0xa0
,
0x52
,
0xe8
,
0x25
,
0x6f
,
0x22
,
0xd0
,
0x4b
,
0xa0
,
0x49
,
0x43
,
0xe3
,
0x69
,
0xe2
,
0x3f
,
0xea
,
0xb0
,
0xe7
,
0xe1
,
0x38
,
0x46
,
0xc5
,
0xd3
,
0xa9
,
0x45
,
0x5b
,
0xfb
,
0x28
,
0xda
,
0x07
,
0xb4
,
0xcd
,
0x34
,
0x0c
,
0xca
,
0x74
,
0x33
,
0x52
,
0x67
,
0x42
,
0x1b
,
0x54
,
0x0a
,
0x71
,
0x6e
,
0x38
,
0xd6
,
0x1b
,
0x94
,
0x24
,
0x8f
,
0xc5
,
0xc6
,
0x66
,
0x16
,
0x43
,
0x7f
,
0x32
,
0x57
,
0x72
,
0x6d
,
0x5e
,
0xcd
,
0xb5
,
0x7a
,
0x8d
,
0xed
,
0xac
,
0xbc
,
0xc6
,
0x6e
,
0x41
,
0xeb
,
0x5c
,
0x8a
,
0x19
,
0x6d
,
0x48
,
0xfb
,
0x16
,
0x72
,
0xf2
,
0x15
,
0x7e
,
0xda
,
0x57
,
0xf9
,
0xf1
,
0x76
,
0x01
,
0x7c
,
0x64
,
0x17
,
0x7c
,
0x05
,
0xd1
,
0x1a
,
0x89
,
0x79
,
0x74
,
0xdf
,
0x9f
,
0xf7
,
0xde
,
0x3a
,
0x8d
,
0xc6
,
0xce
,
0x4c
,
0x7d
,
0x1f
,
0x5a
,
0x76
,
0x99
,
0xd3
,
0xac
,
0x6a
,
0x6c
,
0xee
,
0xfd
,
0x63
,
0x84
,
0xf8
,
0x00
,
0x6e
,
0x32
,
0xbc
,
0x38
,
0xc6
,
0x44
,
0x8c
,
0xe8
,
0x7d
,
0xe6
,
0xbd
,
0x3d
,
0x36
,
0xbe
,
0x76
,
0xe2
,
0xcf
,
0xa1
,
0xfd
,
0x26
,
0x47
,
0x49
,
0x0f
,
0x3a
,
0x32
,
0x11
,
0xf3
,
0x34
,
0x29
,
0x4d
,
0xb4
,
0xa0
,
0xbf
,
0x2e
,
0x89
,
0xc8
,
0x14
,
0xda
,
0xbd
,
0xd0
,
0x66
,
0x4e
,
0x8c
,
0x7f
,
0x84
,
0xce
,
0x9b
,
0xf9
,
0x58
,
0xf2
,
0x11
,
0xbe
,
0x40
,
0xc5
,
0x35
,
0x85
,
0xb9
,
0xe2
,
0x52
,
0xa5
,
0xd9
,
0x98
,
0x3c
,
0xb4
,
0x58
,
0x29
,
0x6b
,
0x27
,
0x97
,
0x28
,
0x73
,
0xb7
,
0xcc
,
0xdb
,
0xcc
,
0x89
,
0x5b
,
0x57
,
0xf9
,
0x09
,
0xec
,
0xd2
,
0xea
,
0xdc
,
0xb2
,
0xb5
,
0xda
,
0xe5
,
0xd6
,
0xea
,
0x43
,
0x27
,
0xcd
,
0x5f
,
0x4f
,
0x84
,
0x54
,
0xda
,
0x94
,
0xdc
,
0xb7
,
0x98
,
0xaf
,
0x7a
,
0x7c
,
0xe7
,
0x87
,
0xff
,
0x8d
,
0x53
,
0x35
,
0x59
,
0x9c
,
0x0d
,
0x12
,
0x31
,
0x3b
,
0x38
,
0x3a
,
0x4a
,
0xb2
,
0x83
,
0x64
,
0xc2
,
0xd3
,
0xec
,
0xe8
,
0xe8
,
0x80
,
0xf8
,
0x3e
,
0x6b
,
0xd2
,
0xdf
,
0xbc
,
0xa3
,
0xbf
,
0x03
,
0x00
,
0x00
,
0xff
,
0xff
,
0x09
,
0x74
,
0x67
,
0x46
,
0x10
,
0x0e
,
0x00
,
0x00
,
}
vendor/github.com/33cn/chain33/types/tx.go
View file @
2b61b2b1
...
...
@@ -778,3 +778,11 @@ func ParseExpire(expire string) (int64, error) {
return
0
,
err
}
//CalcTxShortHash 取txhash的前指定字节,目前默认5
func
CalcTxShortHash
(
hash
[]
byte
)
string
{
if
len
(
hash
)
>=
5
{
return
hex
.
EncodeToString
(
hash
[
0
:
5
])
}
return
""
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment