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
fceee563
Commit
fceee563
authored
Oct 15, 2019
by
caopingcp
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
tendermint remove evidence part
parent
7915e316
Show whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
117 additions
and
1325 deletions
+117
-1325
consensus_state.go
plugin/consensus/tendermint/consensus_state.go
+6
-13
evidence.go
plugin/consensus/tendermint/evidence.go
+0
-431
execution.go
plugin/consensus/tendermint/execution.go
+1
-17
node.go
plugin/consensus/tendermint/node.go
+6
-74
peer_set.go
plugin/consensus/tendermint/peer_set.go
+0
-14
tendermint.go
plugin/consensus/tendermint/tendermint.go
+3
-7
block.go
plugin/consensus/tendermint/types/block.go
+0
-141
evidence.go
plugin/consensus/tendermint/types/evidence.go
+0
-380
round_state.go
plugin/consensus/tendermint/types/round_state.go
+0
-2
signable.go
plugin/consensus/tendermint/types/signable.go
+1
-28
vote_set.go
plugin/consensus/tendermint/types/vote_set.go
+1
-1
tendermint.proto
plugin/dapp/valnode/proto/tendermint.proto
+1
-17
tendermint.pb.go
plugin/dapp/valnode/types/tendermint.pb.go
+98
-200
No files found.
plugin/consensus/tendermint/consensus_state.go
View file @
fceee563
...
...
@@ -65,8 +65,6 @@ type ConsensusState struct {
// TODO: encapsulate all of this in one "BlockManager"
blockExec
*
BlockExecutor
evpool
ttypes
.
EvidencePool
// internal state
mtx
sync
.
Mutex
ttypes
.
RoundState
...
...
@@ -97,14 +95,13 @@ type ConsensusState struct {
}
// NewConsensusState returns a new ConsensusState.
func
NewConsensusState
(
client
*
Client
,
state
State
,
blockExec
*
BlockExecutor
,
evpool
ttypes
.
EvidencePool
)
*
ConsensusState
{
func
NewConsensusState
(
client
*
Client
,
state
State
,
blockExec
*
BlockExecutor
)
*
ConsensusState
{
cs
:=
&
ConsensusState
{
client
:
client
,
blockExec
:
blockExec
,
peerMsgQueue
:
make
(
chan
MsgInfo
,
msgQueueSize
),
internalMsgQueue
:
make
(
chan
MsgInfo
,
msgQueueSize
),
timeoutTicker
:
NewTimeoutTicker
(),
evpool
:
evpool
,
Quit
:
make
(
chan
struct
{}),
txsAvailable
:
make
(
chan
int64
,
1
),
...
...
@@ -554,9 +551,6 @@ func (cs *ConsensusState) enterNewRound(height int64, round int) {
// We've already reset these upon new height,
// and meanwhile we might have received a proposal
// for round 0.
if
cs
.
begCons
.
IsZero
()
{
cs
.
begCons
=
time
.
Now
()
}
}
else
{
tendermintlog
.
Info
(
"Resetting Proposal info"
)
cs
.
Proposal
=
nil
...
...
@@ -756,9 +750,6 @@ func (cs *ConsensusState) createProposalBlock() (block *ttypes.TendermintBlock)
return
nil
}
block
.
Data
=
pblockNew
evidence
:=
cs
.
evpool
.
PendingEvidence
()
block
.
AddEvidence
(
evidence
)
return
block
}
...
...
@@ -1277,13 +1268,11 @@ func (cs *ConsensusState) tryAddVote(voteRaw *tmtypes.Vote, peerID string, peerI
// If it's otherwise invalid, punish peer.
if
err
==
ErrVoteHeightMismatch
{
return
err
}
else
if
voteErr
,
ok
:=
err
.
(
*
ttypes
.
ErrVoteConflictingVotes
);
ok
{
}
else
if
err
==
ttypes
.
ErrVoteConflict
{
if
bytes
.
Equal
(
vote
.
ValidatorAddress
,
cs
.
privValidator
.
GetAddress
())
{
tendermintlog
.
Error
(
"Found conflicting vote from ourselves. Did you unsafe_reset a validator?"
,
"height"
,
vote
.
Height
,
"round"
,
vote
.
Round
,
"type"
,
vote
.
Type
)
return
err
}
err
=
cs
.
evpool
.
AddEvidence
(
voteErr
.
DuplicateVoteEvidence
)
return
err
}
else
{
// Probably an invalid signature / Bad peer.
// Seems this can also err sometimes with "Unexpected step" - perhaps not from a bad peer ?
...
...
@@ -1339,6 +1328,10 @@ func (cs *ConsensusState) addVote(vote *ttypes.Vote, peerID string, peerIP strin
return
}
if
cs
.
begCons
.
IsZero
()
{
cs
.
begCons
=
time
.
Now
()
}
height
:=
cs
.
Height
added
,
err
=
cs
.
Votes
.
AddVote
(
vote
,
peerID
)
if
!
added
{
...
...
plugin/consensus/tendermint/evidence.go
deleted
100644 → 0
View file @
7915e316
// 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
tendermint
import
(
"encoding/json"
"fmt"
"reflect"
"sync"
dbm
"github.com/33cn/chain33/common/db"
ttypes
"github.com/33cn/plugin/plugin/consensus/tendermint/types"
tmtypes
"github.com/33cn/plugin/plugin/dapp/valnode/types"
"github.com/pkg/errors"
)
/*
Requirements:
- Valid new evidence must be persisted immediately and never forgotten
- Uncommitted evidence must be continuously broadcast
- Uncommitted evidence has a partial order, the evidence's priority
Impl:
- First commit atomically in outqueue, pending, lookup.
- Once broadcast, remove from outqueue. No need to sync
- Once committed, atomically remove from pending and update lookup.
- TODO: If we crash after committed but before removing/updating,
we'll be stuck broadcasting evidence we never know we committed.
so either share the state db and atomically MarkCommitted
with ApplyBlock, or check all outqueue/pending on Start to see if its committed
Schema for indexing evidence (note you need both height and hash to find a piece of evidence):
"evidence-lookup"/<evidence-height>/<evidence-hash> -> EvidenceInfo
"evidence-outqueue"/<priority>/<evidence-height>/<evidence-hash> -> EvidenceInfo
"evidence-pending"/<evidence-height>/<evidence-hash> -> EvidenceInfo
*/
type
envelope
struct
{
Kind
string
`json:"type"`
Data
*
json
.
RawMessage
`json:"data"`
}
// EvidenceInfo struct
type
EvidenceInfo
struct
{
Committed
bool
`json:"committed"`
Priority
int64
`json:"priority"`
Evidence
envelope
`json:"evidence"`
}
const
(
baseKeyLookup
=
"evidence-lookup"
// all evidence
baseKeyOutqueue
=
"evidence-outqueue"
// not-yet broadcast
baseKeyPending
=
"evidence-pending"
// broadcast but not committed
)
func
keyLookup
(
evidence
ttypes
.
Evidence
)
[]
byte
{
return
keyLookupFromHeightAndHash
(
evidence
.
Height
(),
evidence
.
Hash
())
}
// big endian padded hex
func
bE
(
h
int64
)
string
{
return
fmt
.
Sprintf
(
"%0.16X"
,
h
)
}
func
keyLookupFromHeightAndHash
(
height
int64
,
hash
[]
byte
)
[]
byte
{
return
_key
(
"%s/%s/%X"
,
baseKeyLookup
,
bE
(
height
),
hash
)
}
func
keyOutqueue
(
evidence
ttypes
.
Evidence
,
priority
int64
)
[]
byte
{
return
_key
(
"%s/%s/%s/%X"
,
baseKeyOutqueue
,
bE
(
priority
),
bE
(
evidence
.
Height
()),
evidence
.
Hash
())
}
func
keyPending
(
evidence
ttypes
.
Evidence
)
[]
byte
{
return
_key
(
"%s/%s/%X"
,
baseKeyPending
,
bE
(
evidence
.
Height
()),
evidence
.
Hash
())
}
func
_key
(
s
string
,
o
...
interface
{})
[]
byte
{
return
[]
byte
(
fmt
.
Sprintf
(
s
,
o
...
))
}
// EvidenceStore is a store of all the evidence we've seen, including
// evidence that has been committed, evidence that has been verified but not broadcast,
// and evidence that has been broadcast but not yet committed.
type
EvidenceStore
struct
{
db
dbm
.
DB
}
// NewEvidenceStore method
func
NewEvidenceStore
(
db
dbm
.
DB
)
*
EvidenceStore
{
if
len
(
ttypes
.
EvidenceType2Type
)
==
0
{
ttypes
.
EvidenceType2Type
=
map
[
string
]
reflect
.
Type
{
ttypes
.
DuplicateVote
:
reflect
.
TypeOf
(
tmtypes
.
DuplicateVoteEvidence
{}),
}
}
if
len
(
ttypes
.
EvidenceType2Obj
)
==
0
{
ttypes
.
EvidenceType2Obj
=
map
[
string
]
ttypes
.
Evidence
{
ttypes
.
DuplicateVote
:
&
ttypes
.
DuplicateVoteEvidence
{},
}
}
return
&
EvidenceStore
{
db
:
db
,
}
}
// PriorityEvidence returns the evidence from the outqueue, sorted by highest priority.
func
(
store
*
EvidenceStore
)
PriorityEvidence
()
(
evidence
[]
ttypes
.
Evidence
)
{
// reverse the order so highest priority is first
l
:=
store
.
ListEvidence
(
baseKeyOutqueue
)
l2
:=
make
([]
ttypes
.
Evidence
,
len
(
l
))
for
i
:=
range
l
{
l2
[
i
]
=
l
[
len
(
l
)
-
1
-
i
]
}
return
l2
}
// PendingEvidence returns all known uncommitted evidence.
func
(
store
*
EvidenceStore
)
PendingEvidence
()
(
evidence
[]
ttypes
.
Evidence
)
{
return
store
.
ListEvidence
(
baseKeyPending
)
}
// ListEvidence lists the evidence for the given prefix key.
// It is wrapped by PriorityEvidence and PendingEvidence for convenience.
func
(
store
*
EvidenceStore
)
ListEvidence
(
prefixKey
string
)
(
evidence
[]
ttypes
.
Evidence
)
{
iter
:=
store
.
db
.
Iterator
([]
byte
(
prefixKey
),
nil
,
false
)
for
iter
.
Next
()
{
val
:=
iter
.
Value
()
evi
,
err
:=
store
.
EvidenceFromInfoBytes
(
val
)
if
err
!=
nil
{
fmt
.
Printf
(
"ListEvidence evidence info unmarshal failed:%v"
,
err
)
}
else
{
evidence
=
append
(
evidence
,
evi
)
}
}
return
evidence
}
// GetEvidence fetches the evidence with the given height and hash.
func
(
store
*
EvidenceStore
)
GetEvidence
(
height
int64
,
hash
[]
byte
)
*
EvidenceInfo
{
key
:=
keyLookupFromHeightAndHash
(
height
,
hash
)
val
,
e
:=
store
.
db
.
Get
(
key
)
if
e
!=
nil
{
fmt
.
Printf
(
fmt
.
Sprintf
(
`GetEvidence: db get key %v failed:%v\n`
,
key
,
e
))
}
if
len
(
val
)
==
0
{
return
nil
}
var
ei
EvidenceInfo
err
:=
json
.
Unmarshal
(
val
,
&
ei
)
if
err
!=
nil
{
fmt
.
Printf
(
fmt
.
Sprintf
(
`GetEvidence: unmarshal failed:%v\n`
,
err
))
}
return
&
ei
}
// AddNewEvidence adds the given evidence to the database.
// It returns false if the evidence is already stored.
func
(
store
*
EvidenceStore
)
AddNewEvidence
(
evidence
ttypes
.
Evidence
,
priority
int64
)
bool
{
// check if we already have seen it
ei
:=
store
.
GetEvidence
(
evidence
.
Height
(),
evidence
.
Hash
())
if
ei
!=
nil
&&
len
(
ei
.
Evidence
.
Kind
)
==
0
{
return
false
}
eiBytes
,
err
:=
EvidenceToInfoBytes
(
evidence
,
priority
)
if
err
!=
nil
{
fmt
.
Printf
(
"AddNewEvidence failed:%v
\n
"
,
err
)
return
false
}
// add it to the store
key
:=
keyOutqueue
(
evidence
,
priority
)
if
err
=
store
.
db
.
Set
(
key
,
eiBytes
);
err
!=
nil
{
fmt
.
Printf
(
"AddNewEvidence Set failed:%v
\n
"
,
err
)
return
false
}
key
=
keyPending
(
evidence
)
if
err
=
store
.
db
.
Set
(
key
,
eiBytes
);
err
!=
nil
{
fmt
.
Printf
(
"AddNewEvidence Set failed:%v
\n
"
,
err
)
return
false
}
key
=
keyLookup
(
evidence
)
if
err
=
store
.
db
.
SetSync
(
key
,
eiBytes
);
err
!=
nil
{
fmt
.
Printf
(
"AddNewEvidence SetSync failed:%v
\n
"
,
err
)
return
false
}
return
true
}
// MarkEvidenceAsBroadcasted removes evidence from Outqueue.
func
(
store
*
EvidenceStore
)
MarkEvidenceAsBroadcasted
(
evidence
ttypes
.
Evidence
)
{
ei
:=
store
.
getEvidenceInfo
(
evidence
)
key
:=
keyOutqueue
(
evidence
,
ei
.
Priority
)
if
err
:=
store
.
db
.
Delete
(
key
);
err
!=
nil
{
fmt
.
Printf
(
"MarkEvidenceAsBroadcasted Delete failed:%v"
,
err
)
}
}
// MarkEvidenceAsCommitted removes evidence from pending and outqueue and sets the state to committed.
func
(
store
*
EvidenceStore
)
MarkEvidenceAsCommitted
(
evidence
ttypes
.
Evidence
)
{
// if its committed, its been broadcast
store
.
MarkEvidenceAsBroadcasted
(
evidence
)
pendingKey
:=
keyPending
(
evidence
)
if
err
:=
store
.
db
.
Delete
(
pendingKey
);
err
!=
nil
{
fmt
.
Printf
(
"MarkEvidenceAsCommitted Delete failed:%v"
,
err
)
}
ei
:=
store
.
getEvidenceInfo
(
evidence
)
ei
.
Committed
=
true
lookupKey
:=
keyLookup
(
evidence
)
eiBytes
,
err
:=
json
.
Marshal
(
ei
)
if
err
!=
nil
{
fmt
.
Printf
(
"MarkEvidenceAsCommitted marshal failed:%v"
,
err
)
}
if
err
=
store
.
db
.
SetSync
(
lookupKey
,
eiBytes
);
err
!=
nil
{
fmt
.
Printf
(
"MarkEvidenceAsCommitted SetSync failed:%v"
,
err
)
}
}
//---------------------------------------------------
// utils
func
(
store
*
EvidenceStore
)
getEvidenceInfo
(
evidence
ttypes
.
Evidence
)
EvidenceInfo
{
key
:=
keyLookup
(
evidence
)
var
ei
EvidenceInfo
b
,
e
:=
store
.
db
.
Get
(
key
)
if
e
!=
nil
{
fmt
.
Printf
(
fmt
.
Sprintf
(
`getEvidenceInfo: db get key %v failed:%v\n`
,
key
,
e
))
}
err
:=
json
.
Unmarshal
(
b
,
&
ei
)
if
err
!=
nil
{
fmt
.
Printf
(
fmt
.
Sprintf
(
`getEvidenceInfo: Unmarshal failed:%v\n`
,
err
))
}
return
ei
}
// EvidenceToInfoBytes method
func
EvidenceToInfoBytes
(
evidence
ttypes
.
Evidence
,
priority
int64
)
([]
byte
,
error
)
{
evi
,
err
:=
json
.
Marshal
(
evidence
)
if
err
!=
nil
{
return
nil
,
errors
.
Errorf
(
"EvidenceToBytes marshal evidence failed:%v
\n
"
,
err
)
}
msg
:=
json
.
RawMessage
(
evi
)
env
:=
envelope
{
Kind
:
evidence
.
TypeName
(),
Data
:
&
msg
,
}
ei
:=
EvidenceInfo
{
Committed
:
false
,
Priority
:
priority
,
Evidence
:
env
,
}
eiBytes
,
err
:=
json
.
Marshal
(
ei
)
if
err
!=
nil
{
return
nil
,
errors
.
Errorf
(
"EvidenceToBytes marshal evidence info failed:%v
\n
"
,
err
)
}
return
eiBytes
,
nil
}
// EvidenceFromInfoBytes method
func
(
store
*
EvidenceStore
)
EvidenceFromInfoBytes
(
data
[]
byte
)
(
ttypes
.
Evidence
,
error
)
{
vote2
:=
EvidenceInfo
{}
err
:=
json
.
Unmarshal
(
data
,
&
vote2
)
if
err
!=
nil
{
return
nil
,
errors
.
Errorf
(
"BytesToEvidence Unmarshal evidence info failed:%v
\n
"
,
err
)
}
if
v
,
ok
:=
ttypes
.
EvidenceType2Type
[
vote2
.
Evidence
.
Kind
];
ok
{
tmp
:=
v
.
(
ttypes
.
Evidence
)
.
Copy
()
err
=
json
.
Unmarshal
(
*
vote2
.
Evidence
.
Data
,
&
tmp
)
if
err
!=
nil
{
return
nil
,
errors
.
Errorf
(
"BytesToEvidence Unmarshal evidence failed:%v
\n
"
,
err
)
}
return
tmp
,
nil
}
return
nil
,
errors
.
Errorf
(
"BytesToEvidence not find evidence kind:%v
\n
"
,
vote2
.
Evidence
.
Kind
)
}
// EvidencePool maintains a pool of valid evidence
// in an EvidenceStore.
type
EvidencePool
struct
{
evidenceStore
*
EvidenceStore
// needed to load validators to verify evidence
stateDB
*
CSStateDB
// latest state
mtx
sync
.
Mutex
state
State
// never close
evidenceChan
chan
ttypes
.
Evidence
}
// NewEvidencePool method
func
NewEvidencePool
(
stateDB
*
CSStateDB
,
state
State
,
evidenceStore
*
EvidenceStore
)
*
EvidencePool
{
evpool
:=
&
EvidencePool
{
stateDB
:
stateDB
,
state
:
state
,
evidenceStore
:
evidenceStore
,
evidenceChan
:
make
(
chan
ttypes
.
Evidence
),
}
return
evpool
}
// EvidenceChan returns an unbuffered channel on which new evidence can be received.
func
(
evpool
*
EvidencePool
)
EvidenceChan
()
<-
chan
ttypes
.
Evidence
{
return
evpool
.
evidenceChan
}
// PriorityEvidence returns the priority evidence.
func
(
evpool
*
EvidencePool
)
PriorityEvidence
()
[]
ttypes
.
Evidence
{
return
evpool
.
evidenceStore
.
PriorityEvidence
()
}
// PendingEvidence returns all uncommitted evidence.
func
(
evpool
*
EvidencePool
)
PendingEvidence
()
[]
ttypes
.
Evidence
{
return
evpool
.
evidenceStore
.
PendingEvidence
()
}
// State returns the current state of the evpool.
func
(
evpool
*
EvidencePool
)
State
()
State
{
evpool
.
mtx
.
Lock
()
defer
evpool
.
mtx
.
Unlock
()
return
evpool
.
state
}
// Update loads the latest
func
(
evpool
*
EvidencePool
)
Update
(
block
*
ttypes
.
TendermintBlock
)
{
evpool
.
mtx
.
Lock
()
defer
evpool
.
mtx
.
Unlock
()
state
:=
evpool
.
stateDB
.
LoadState
()
if
state
.
LastBlockHeight
!=
block
.
Header
.
Height
{
panic
(
fmt
.
Sprintf
(
"EvidencePool.Update: loaded state with height %d when block.Height=%d"
,
state
.
LastBlockHeight
,
block
.
Header
.
Height
))
}
evpool
.
state
=
state
// NOTE: shouldn't need the mutex
evpool
.
MarkEvidenceAsCommitted
(
block
.
Evidence
.
Evidence
)
}
// AddEvidence checks the evidence is valid and adds it to the pool.
// Blocks on the EvidenceChan.
func
(
evpool
*
EvidencePool
)
AddEvidence
(
evidence
ttypes
.
Evidence
)
error
{
// TODO: check if we already have evidence for this
// validator at this height so we dont get spammed
if
err
:=
VerifyEvidence
(
evpool
.
stateDB
,
evpool
.
State
(),
evidence
);
err
!=
nil
{
return
err
}
// fetch the validator and return its voting power as its priority
// TODO: something better ?
valset
,
err
:=
evpool
.
stateDB
.
LoadValidators
(
evidence
.
Height
())
if
err
!=
nil
{
return
err
}
_
,
val
:=
valset
.
GetByAddress
(
evidence
.
Address
())
priority
:=
val
.
VotingPower
added
:=
evpool
.
evidenceStore
.
AddNewEvidence
(
evidence
,
priority
)
if
!
added
{
// evidence already known, just ignore
return
nil
}
tendermintlog
.
Info
(
"Verified new evidence of byzantine behaviour"
,
"evidence"
,
evidence
)
// never closes. always safe to send on
evpool
.
evidenceChan
<-
evidence
return
nil
}
// MarkEvidenceAsCommitted marks all the evidence as committed.
func
(
evpool
*
EvidencePool
)
MarkEvidenceAsCommitted
(
evidence
[]
*
tmtypes
.
EvidenceEnvelope
)
{
for
_
,
ev
:=
range
evidence
{
tmp
:=
ttypes
.
EvidenceEnvelope2Evidence
(
ev
)
if
tmp
!=
nil
{
evpool
.
evidenceStore
.
MarkEvidenceAsCommitted
(
tmp
)
}
}
}
// VerifyEvidence verifies the evidence fully by checking it is internally
// consistent and sufficiently recent.
func
VerifyEvidence
(
stateDB
*
CSStateDB
,
s
State
,
evidence
ttypes
.
Evidence
)
error
{
height
:=
s
.
LastBlockHeight
evidenceAge
:=
height
-
evidence
.
Height
()
maxAge
:=
s
.
ConsensusParams
.
EvidenceParams
.
MaxAge
if
evidenceAge
>
maxAge
{
return
fmt
.
Errorf
(
"Evidence from height %d is too old. Min height is %d"
,
evidence
.
Height
(),
height
-
maxAge
)
}
if
err
:=
evidence
.
Verify
(
s
.
ChainID
);
err
!=
nil
{
return
err
}
valset
,
err
:=
stateDB
.
LoadValidators
(
evidence
.
Height
())
if
err
!=
nil
{
// TODO: if err is just that we cant find it cuz we pruned, ignore.
// TODO: if its actually bad evidence, punish peer
return
err
}
// The address must have been an active validator at the height
ev
:=
evidence
height
,
addr
,
idx
:=
ev
.
Height
(),
ev
.
Address
(),
ev
.
Index
()
valIdx
,
val
:=
valset
.
GetByAddress
(
addr
)
if
val
==
nil
{
return
fmt
.
Errorf
(
"Address %X was not a validator at height %d"
,
addr
,
height
)
}
else
if
idx
!=
valIdx
{
return
fmt
.
Errorf
(
"Address %X was validator %d at height %d, not %d"
,
addr
,
valIdx
,
height
,
idx
)
}
return
nil
}
plugin/consensus/tendermint/execution.go
View file @
fceee563
...
...
@@ -22,15 +22,13 @@ import (
type
BlockExecutor
struct
{
// save state, validators, consensus params, abci responses here
db
*
CSStateDB
evpool
ttypes
.
EvidencePool
}
// NewBlockExecutor returns a new BlockExecutor with a NopEventBus.
// Call SetEventBus to provide one.
func
NewBlockExecutor
(
db
*
CSStateDB
,
evpool
ttypes
.
EvidencePool
)
*
BlockExecutor
{
func
NewBlockExecutor
(
db
*
CSStateDB
)
*
BlockExecutor
{
return
&
BlockExecutor
{
db
:
db
,
evpool
:
evpool
,
}
}
...
...
@@ -59,12 +57,6 @@ func (blockExec *BlockExecutor) ApplyBlock(s State, blockID ttypes.BlockID, bloc
}
blockExec
.
db
.
SaveState
(
s
)
// Update evpool now that state is saved
// TODO: handle the crash/recover scenario
// ie. (may need to call Update for last block)
blockExec
.
evpool
.
Update
(
block
)
return
s
,
nil
}
...
...
@@ -246,13 +238,5 @@ func validateBlock(stateDB *CSStateDB, s State, b *ttypes.TendermintBlock) error
}
}
for
_
,
ev
:=
range
b
.
Evidence
.
Evidence
{
evidence
:=
ttypes
.
EvidenceEnvelope2Evidence
(
ev
)
if
evidence
!=
nil
{
if
err
:=
VerifyEvidence
(
stateDB
,
s
,
evidence
);
err
!=
nil
{
return
ttypes
.
NewEvidenceInvalidErr
(
evidence
,
err
)
}
}
}
return
nil
}
plugin/consensus/tendermint/node.go
View file @
fceee563
...
...
@@ -17,8 +17,6 @@ import (
"github.com/33cn/chain33/common/crypto"
ttypes
"github.com/33cn/plugin/plugin/consensus/tendermint/types"
tmtypes
"github.com/33cn/plugin/plugin/dapp/valnode/types"
"github.com/golang/protobuf/proto"
)
const
(
...
...
@@ -132,7 +130,6 @@ type Node struct {
lAddr
string
state
*
ConsensusState
evpool
*
EvidencePool
broadcastChannel
chan
MsgInfo
started
uint32
// atomic
stopped
uint32
// atomic
...
...
@@ -140,7 +137,7 @@ type Node struct {
}
// NewNode method
func
NewNode
(
seeds
[]
string
,
protocol
string
,
lAddr
string
,
privKey
crypto
.
PrivKey
,
network
string
,
version
string
,
state
*
ConsensusState
,
evpool
*
EvidencePool
)
*
Node
{
func
NewNode
(
seeds
[]
string
,
protocol
string
,
lAddr
string
,
privKey
crypto
.
PrivKey
,
network
string
,
version
string
,
state
*
ConsensusState
)
*
Node
{
address
:=
GenAddressByPubKey
(
privKey
.
PubKey
())
node
:=
&
Node
{
...
...
@@ -158,7 +155,6 @@ func NewNode(seeds []string, protocol string, lAddr string, privKey crypto.PrivK
reconnecting
:
NewMutexMap
(),
broadcastChannel
:
make
(
chan
MsgInfo
,
maxSendQueueSize
),
state
:
state
,
evpool
:
evpool
,
localIPs
:
make
(
map
[
string
]
net
.
IP
),
}
...
...
@@ -219,7 +215,6 @@ func (node *Node) Start() {
go
node
.
StartConsensusRoutine
()
go
node
.
BroadcastRoutine
()
go
node
.
evidenceBroadcastRoutine
()
}
}
...
...
@@ -234,7 +229,7 @@ func (node *Node) DialPeerWithAddress(addr string) error {
func
(
node
*
Node
)
addOutboundPeerWithConfig
(
addr
string
)
error
{
tendermintlog
.
Info
(
"Dialing peer"
,
"address"
,
addr
)
peerConn
,
err
:=
newOutboundPeerConn
(
addr
,
node
.
privKey
,
node
.
StopPeerForError
,
node
.
state
,
node
.
evpool
)
peerConn
,
err
:=
newOutboundPeerConn
(
addr
,
node
.
privKey
,
node
.
StopPeerForError
,
node
.
state
)
if
err
!=
nil
{
go
node
.
reconnectToPeer
(
addr
)
return
err
...
...
@@ -307,66 +302,6 @@ func (node *Node) StartConsensusRoutine() {
}
}
func
(
node
*
Node
)
evidenceBroadcastRoutine
()
{
ticker
:=
time
.
NewTicker
(
time
.
Second
*
broadcastEvidenceIntervalS
)
for
{
select
{
case
evidence
:=
<-
node
.
evpool
.
EvidenceChan
()
:
// broadcast some new evidence
data
,
err
:=
proto
.
Marshal
(
evidence
.
Child
())
if
err
!=
nil
{
msg
:=
MsgInfo
{
TypeID
:
ttypes
.
EvidenceListID
,
Msg
:
&
tmtypes
.
EvidenceData
{
Evidence
:
[]
*
tmtypes
.
EvidenceEnvelope
{
{
TypeName
:
evidence
.
TypeName
(),
Data
:
data
,
},
},
},
PeerID
:
node
.
ID
,
PeerIP
:
node
.
IP
,
}
node
.
Broadcast
(
msg
)
// TODO: Broadcast runs asynchronously, so this should wait on the successChan
// in another routine before marking to be proper.
node
.
evpool
.
evidenceStore
.
MarkEvidenceAsBroadcasted
(
evidence
)
}
case
<-
ticker
.
C
:
// broadcast all pending evidence
var
eData
tmtypes
.
EvidenceData
evidence
:=
node
.
evpool
.
PendingEvidence
()
for
_
,
item
:=
range
evidence
{
ev
:=
item
.
Child
()
if
ev
!=
nil
{
data
,
err
:=
proto
.
Marshal
(
ev
)
if
err
!=
nil
{
panic
(
"AddEvidence marshal failed"
)
}
env
:=
&
tmtypes
.
EvidenceEnvelope
{
TypeName
:
item
.
TypeName
(),
Data
:
data
,
}
eData
.
Evidence
=
append
(
eData
.
Evidence
,
env
)
}
}
msg
:=
MsgInfo
{
TypeID
:
ttypes
.
EvidenceListID
,
Msg
:
&
eData
,
PeerID
:
node
.
ID
,
PeerIP
:
node
.
IP
,
}
node
.
Broadcast
(
msg
)
case
_
,
ok
:=
<-
node
.
quit
:
if
!
ok
{
node
.
quit
=
nil
tendermintlog
.
Info
(
"evidenceBroadcastRoutine quit"
)
return
}
}
}
}
// BroadcastRoutine receive to broadcast
func
(
node
*
Node
)
BroadcastRoutine
()
{
for
{
...
...
@@ -413,7 +348,7 @@ func (node *Node) StopPeerForError(peer Peer, reason interface{}) {
}
func
(
node
*
Node
)
addInboundPeer
(
conn
net
.
Conn
)
error
{
peerConn
,
err
:=
newInboundPeerConn
(
conn
,
node
.
privKey
,
node
.
StopPeerForError
,
node
.
state
,
node
.
evpool
)
peerConn
,
err
:=
newInboundPeerConn
(
conn
,
node
.
privKey
,
node
.
StopPeerForError
,
node
.
state
)
if
err
!=
nil
{
if
er
:=
conn
.
Close
();
er
!=
nil
{
tendermintlog
.
Error
(
"addInboundPeer close conn failed"
,
"er"
,
er
)
...
...
@@ -710,13 +645,13 @@ func dial(addr string) (net.Conn, error) {
return
conn
,
nil
}
func
newOutboundPeerConn
(
addr
string
,
ourNodePrivKey
crypto
.
PrivKey
,
onPeerError
func
(
Peer
,
interface
{}),
state
*
ConsensusState
,
evpool
*
EvidencePool
)
(
*
peerConn
,
error
)
{
func
newOutboundPeerConn
(
addr
string
,
ourNodePrivKey
crypto
.
PrivKey
,
onPeerError
func
(
Peer
,
interface
{}),
state
*
ConsensusState
)
(
*
peerConn
,
error
)
{
conn
,
err
:=
dial
(
addr
)
if
err
!=
nil
{
return
&
peerConn
{},
fmt
.
Errorf
(
"Error creating peer:%v"
,
err
)
}
pc
,
err
:=
newPeerConn
(
conn
,
true
,
true
,
ourNodePrivKey
,
onPeerError
,
state
,
evpool
)
pc
,
err
:=
newPeerConn
(
conn
,
true
,
true
,
ourNodePrivKey
,
onPeerError
,
state
)
if
err
!=
nil
{
if
cerr
:=
conn
.
Close
();
cerr
!=
nil
{
return
&
peerConn
{},
fmt
.
Errorf
(
"newPeerConn failed:%v, connection close failed:%v"
,
err
,
cerr
)
...
...
@@ -732,12 +667,11 @@ func newInboundPeerConn(
ourNodePrivKey
crypto
.
PrivKey
,
onPeerError
func
(
Peer
,
interface
{}),
state
*
ConsensusState
,
evpool
*
EvidencePool
,
)
(
*
peerConn
,
error
)
{
// TODO: issue PoW challenge
return
newPeerConn
(
conn
,
false
,
false
,
ourNodePrivKey
,
onPeerError
,
state
,
evpool
)
return
newPeerConn
(
conn
,
false
,
false
,
ourNodePrivKey
,
onPeerError
,
state
)
}
func
newPeerConn
(
...
...
@@ -746,7 +680,6 @@ func newPeerConn(
ourNodePrivKey
crypto
.
PrivKey
,
onPeerError
func
(
Peer
,
interface
{}),
state
*
ConsensusState
,
evpool
*
EvidencePool
,
)
(
pc
*
peerConn
,
err
error
)
{
conn
:=
rawConn
...
...
@@ -769,6 +702,5 @@ func newPeerConn(
conn
:
conn
,
onPeerError
:
onPeerError
,
myState
:
state
,
myevpool
:
evpool
,
},
nil
}
plugin/consensus/tendermint/peer_set.go
View file @
fceee563
...
...
@@ -95,7 +95,6 @@ type peerConn struct {
onPeerError
func
(
Peer
,
interface
{})
myState
*
ConsensusState
myevpool
*
EvidencePool
state
*
PeerConnState
updateStateQueue
chan
MsgInfo
...
...
@@ -579,19 +578,6 @@ FOR_LOOP:
}
}
else
if
pkt
.
TypeID
==
ttypes
.
ProposalHeartbeatID
{
pc
.
heartbeatQueue
<-
realMsg
.
(
*
tmtypes
.
Heartbeat
)
}
else
if
pkt
.
TypeID
==
ttypes
.
EvidenceListID
{
go
func
()
{
for
_
,
ev
:=
range
realMsg
.
(
*
tmtypes
.
EvidenceData
)
.
Evidence
{
evidence
:=
ttypes
.
EvidenceEnvelope2Evidence
(
ev
)
if
evidence
!=
nil
{
err
:=
pc
.
myevpool
.
AddEvidence
(
evidence
.
(
ttypes
.
Evidence
))
if
err
!=
nil
{
tendermintlog
.
Error
(
"Evidence is not valid"
,
"evidence"
,
ev
,
"err"
,
err
)
// TODO: punish peer
}
}
}
}()
}
else
{
pc
.
updateStateQueue
<-
MsgInfo
{
pkt
.
TypeID
,
realMsg
.
(
proto
.
Message
),
pc
.
ID
(),
pc
.
ip
.
String
()}
}
...
...
plugin/consensus/tendermint/tendermint.go
View file @
fceee563
...
...
@@ -295,15 +295,11 @@ OuterLoop:
stateDB
:=
NewStateDB
(
client
,
state
)
//make evidenceReactor
evidenceStore
:=
NewEvidenceStore
(
client
.
evidenceDB
)
evidencePool
:=
NewEvidencePool
(
stateDB
,
state
,
evidenceStore
)
// make block executor for consensus and blockchain reactors to execute blocks
blockExec
:=
NewBlockExecutor
(
stateDB
,
evidencePool
)
blockExec
:=
NewBlockExecutor
(
stateDB
)
// Make ConsensusReactor
csState
:=
NewConsensusState
(
client
,
state
,
blockExec
,
evidencePool
)
csState
:=
NewConsensusState
(
client
,
state
,
blockExec
)
// reset height, round, state begin at newheigt,0,0
client
.
privValidator
.
ResetLastHeight
(
state
.
LastBlockHeight
)
csState
.
SetPrivValidator
(
client
.
privValidator
)
...
...
@@ -312,7 +308,7 @@ OuterLoop:
// Create & add listener
protocol
,
listeningAddress
:=
"tcp"
,
"0.0.0.0:46656"
node
:=
NewNode
(
validatorNodes
,
protocol
,
listeningAddress
,
client
.
privKey
,
state
.
ChainID
,
tendermintVersion
,
csState
,
evidencePool
)
node
:=
NewNode
(
validatorNodes
,
protocol
,
listeningAddress
,
client
.
privKey
,
state
.
ChainID
,
tendermintVersion
,
csState
)
client
.
node
=
node
node
.
Start
()
...
...
plugin/consensus/tendermint/types/block.go
View file @
fceee563
...
...
@@ -17,7 +17,6 @@ import (
"github.com/33cn/chain33/common/merkle"
"github.com/33cn/chain33/types"
tmtypes
"github.com/33cn/plugin/plugin/dapp/valnode/types"
"github.com/golang/protobuf/proto"
)
var
(
...
...
@@ -69,32 +68,12 @@ func MakeBlock(height int64, round int64, pblock *types.Block, commit *tmtypes.T
},
Data
:
pblock
,
LastCommit
:
commit
,
Evidence
:
&
tmtypes
.
EvidenceData
{
Evidence
:
make
([]
*
tmtypes
.
EvidenceEnvelope
,
0
)},
},
}
block
.
FillHeader
()
return
block
}
// AddEvidence appends the given evidence to the block
func
(
b
*
TendermintBlock
)
AddEvidence
(
evidence
[]
Evidence
)
{
for
_
,
item
:=
range
evidence
{
ev
:=
item
.
Child
()
if
ev
!=
nil
{
data
,
err
:=
proto
.
Marshal
(
ev
)
if
err
!=
nil
{
blocklog
.
Error
(
"AddEvidence marshal failed"
,
"error"
,
err
)
panic
(
"AddEvidence marshal failed"
)
}
env
:=
&
tmtypes
.
EvidenceEnvelope
{
TypeName
:
item
.
TypeName
(),
Data
:
data
,
}
b
.
Evidence
.
Evidence
=
append
(
b
.
Evidence
.
Evidence
,
env
)
}
}
}
// ValidateBasic performs basic validation that doesn't involve state data.
// It checks the internal consistency of the block.
// Further validation is done using state#ValidateBlock.
...
...
@@ -133,10 +112,6 @@ func (b *TendermintBlock) ValidateBasic() error {
return
fmt
.
Errorf
(
"Wrong Header.LastCommitHash. Expected %v, got %v"
,
b
.
Header
.
LastCommitHash
,
lastCommit
.
Hash
())
}
evidence
:=
&
EvidenceData
{
EvidenceData
:
b
.
Evidence
}
if
!
bytes
.
Equal
(
b
.
Header
.
EvidenceHash
,
evidence
.
Hash
())
{
return
errors
.
New
(
Fmt
(
"Wrong Header.EvidenceHash. Expected %v, got %v"
,
b
.
Header
.
EvidenceHash
,
evidence
.
Hash
()))
}
return
nil
}
...
...
@@ -148,10 +123,6 @@ func (b *TendermintBlock) FillHeader() {
}
b
.
Header
.
LastCommitHash
=
lastCommit
.
Hash
()
}
if
b
.
Header
.
EvidenceHash
==
nil
{
evidence
:=
&
EvidenceData
{
EvidenceData
:
b
.
Evidence
}
b
.
Header
.
EvidenceHash
=
evidence
.
Hash
()
}
}
// Hash computes and returns the block hash.
...
...
@@ -246,7 +217,6 @@ func (h *Header) StringIndented(indent string) string {
%s App: %v
%s Conensus: %v
%s Results: %v
%s Evidence: %v
%s}#%v`
,
indent
,
h
.
ChainID
,
indent
,
h
.
Height
,
...
...
@@ -259,7 +229,6 @@ func (h *Header) StringIndented(indent string) string {
indent
,
h
.
AppHash
,
indent
,
h
.
ConsensusHash
,
indent
,
h
.
LastResultsHash
,
indent
,
h
.
EvidenceHash
,
indent
,
h
.
Hash
())
}
...
...
@@ -410,113 +379,3 @@ type SignedHeader struct {
Header
*
Header
`json:"header"`
Commit
*
Commit
`json:"commit"`
}
// EvidenceEnvelope ...
type
EvidenceEnvelope
struct
{
*
tmtypes
.
EvidenceEnvelope
}
// EvidenceEnvelopeList contains any evidence of malicious wrong-doing by validators
type
EvidenceEnvelopeList
[]
EvidenceEnvelope
// Hash ...
func
(
env
EvidenceEnvelope
)
Hash
()
[]
byte
{
penv
:=
env
.
EvidenceEnvelope
evidence
:=
EvidenceEnvelope2Evidence
(
penv
)
if
evidence
!=
nil
{
return
evidence
.
Hash
()
}
return
nil
}
func
(
env
EvidenceEnvelope
)
String
()
string
{
penv
:=
env
.
EvidenceEnvelope
evidence
:=
EvidenceEnvelope2Evidence
(
penv
)
if
evidence
!=
nil
{
return
evidence
.
String
()
}
return
""
}
// Hash returns the simple merkle root hash of the EvidenceList.
func
(
evl
EvidenceEnvelopeList
)
Hash
()
[]
byte
{
// Recursive impl.
// Copied from tmlibs/merkle to avoid allocations
switch
len
(
evl
)
{
case
0
:
return
nil
case
1
:
return
evl
[
0
]
.
Hash
()
default
:
left
:=
evl
[
:
(
len
(
evl
)
+
1
)
/
2
]
.
Hash
()
right
:=
evl
[(
len
(
evl
)
+
1
)
/
2
:
]
.
Hash
()
cache
:=
make
([]
byte
,
len
(
left
)
+
len
(
right
))
return
merkle
.
GetHashFromTwoHash
(
cache
,
left
,
right
)
}
}
func
(
evl
EvidenceEnvelopeList
)
String
()
string
{
s
:=
""
for
_
,
e
:=
range
evl
{
s
+=
Fmt
(
"%s
\t\t
"
,
e
)
}
return
s
}
// Has returns true if the evidence is in the EvidenceList.
func
(
evl
EvidenceEnvelopeList
)
Has
(
evidence
Evidence
)
bool
{
for
_
,
ev
:=
range
evl
{
penv
:=
ev
.
EvidenceEnvelope
tmp
:=
EvidenceEnvelope2Evidence
(
penv
)
if
tmp
!=
nil
{
if
tmp
.
Equal
(
evidence
)
{
return
true
}
}
}
return
false
}
// EvidenceData ...
type
EvidenceData
struct
{
*
tmtypes
.
EvidenceData
hash
[]
byte
}
// Hash returns the hash of the data.
func
(
data
*
EvidenceData
)
Hash
()
[]
byte
{
if
data
.
hash
==
nil
{
if
data
.
EvidenceData
==
nil
{
return
nil
}
var
evidence
EvidenceEnvelopeList
for
_
,
item
:=
range
data
.
Evidence
{
elem
:=
EvidenceEnvelope
{
EvidenceEnvelope
:
item
,
}
evidence
=
append
(
evidence
,
elem
)
}
data
.
hash
=
evidence
.
Hash
()
}
return
data
.
hash
}
// StringIndented returns a string representation of the evidence.
func
(
data
*
EvidenceData
)
StringIndented
(
indent
string
)
string
{
if
data
==
nil
{
return
"nil-Evidence"
}
evStrings
:=
make
([]
string
,
MinInt
(
len
(
data
.
Evidence
),
21
))
for
i
,
ev
:=
range
data
.
Evidence
{
if
i
==
20
{
evStrings
[
i
]
=
Fmt
(
"... (%v total)"
,
len
(
data
.
Evidence
))
break
}
evStrings
[
i
]
=
Fmt
(
"Evidence:%v"
,
ev
)
}
return
Fmt
(
`Data{
%s %v
%s}#%v`
,
indent
,
strings
.
Join
(
evStrings
,
"
\n
"
+
indent
+
" "
),
indent
,
data
.
hash
)
}
plugin/consensus/tendermint/types/evidence.go
deleted
100644 → 0
View file @
7915e316
// 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
(
"bytes"
"encoding/json"
"fmt"
"reflect"
"github.com/33cn/chain33/common/crypto"
"github.com/33cn/chain33/common/merkle"
tmtypes
"github.com/33cn/plugin/plugin/dapp/valnode/types"
"github.com/golang/protobuf/proto"
)
// ErrEvidenceInvalid wraps a piece of evidence and the error denoting how or why it is invalid.
type
ErrEvidenceInvalid
struct
{
Evidence
Evidence
ErrorValue
error
}
// NewEvidenceInvalidErr ...
func
NewEvidenceInvalidErr
(
ev
Evidence
,
err
error
)
*
ErrEvidenceInvalid
{
return
&
ErrEvidenceInvalid
{
ev
,
err
}
}
// Error returns a string representation of the error.
func
(
err
*
ErrEvidenceInvalid
)
Error
()
string
{
return
Fmt
(
"Invalid evidence: %v. Evidence: %v"
,
err
.
ErrorValue
,
err
.
Evidence
)
}
//-------------------------------------------
const
(
DuplicateVote
=
"DuplicateVote"
MockGood
=
"MockGood"
MockBad
=
"MockBad"
)
// EvidenceType map define
var
(
EvidenceType2Type
map
[
string
]
reflect
.
Type
EvidenceType2Obj
map
[
string
]
Evidence
)
// Evidence represents any provable malicious activity by a validator
type
Evidence
interface
{
Height
()
int64
// height of the equivocation
Address
()
[]
byte
// address of the equivocating validator
Index
()
int
// index of the validator in the validator set
Hash
()
[]
byte
// hash of the evidence
Verify
(
chainID
string
)
error
// verify the evidence
Equal
(
Evidence
)
bool
// check equality of evidence
String
()
string
Copy
()
Evidence
TypeName
()
string
SetChild
(
child
proto
.
Message
)
Child
()
proto
.
Message
}
//-------------------------------------------
// EvidenceList is a list of Evidence. Evidences is not a word.
type
EvidenceList
[]
Evidence
// Hash returns the simple merkle root hash of the EvidenceList.
func
(
evl
EvidenceList
)
Hash
()
[]
byte
{
// Recursive impl.
// Copied from tmlibs/merkle to avoid allocations
switch
len
(
evl
)
{
case
0
:
return
nil
case
1
:
return
evl
[
0
]
.
Hash
()
default
:
left
:=
evl
[
:
(
len
(
evl
)
+
1
)
/
2
]
.
Hash
()
right
:=
evl
[(
len
(
evl
)
+
1
)
/
2
:
]
.
Hash
()
cache
:=
make
([]
byte
,
len
(
left
)
+
len
(
right
))
return
merkle
.
GetHashFromTwoHash
(
cache
,
left
,
right
)
}
}
func
(
evl
EvidenceList
)
String
()
string
{
s
:=
""
for
_
,
e
:=
range
evl
{
s
+=
Fmt
(
"%s
\t\t
"
,
e
)
}
return
s
}
// Has returns true if the evidence is in the EvidenceList.
func
(
evl
EvidenceList
)
Has
(
evidence
Evidence
)
bool
{
for
_
,
ev
:=
range
evl
{
if
ev
.
Equal
(
evidence
)
{
return
true
}
}
return
false
}
//-------------------------------------------
// DuplicateVoteEvidence contains evidence a validator signed two conflicting votes.
type
DuplicateVoteEvidence
struct
{
*
tmtypes
.
DuplicateVoteEvidence
}
// String returns a string representation of the evidence.
func
(
dve
*
DuplicateVoteEvidence
)
String
()
string
{
return
Fmt
(
"VoteA: %v; VoteB: %v"
,
dve
.
VoteA
,
dve
.
VoteB
)
}
// Height returns the height this evidence refers to.
func
(
dve
*
DuplicateVoteEvidence
)
Height
()
int64
{
return
dve
.
VoteA
.
Height
}
// Address returns the address of the validator.
func
(
dve
*
DuplicateVoteEvidence
)
Address
()
[]
byte
{
pubkey
,
err
:=
PubKeyFromString
(
dve
.
PubKey
)
if
err
!=
nil
{
return
nil
}
return
GenAddressByPubKey
(
pubkey
)
}
// Index returns the index of the validator.
func
(
dve
*
DuplicateVoteEvidence
)
Index
()
int
{
return
int
(
dve
.
VoteA
.
ValidatorIndex
)
}
// Hash returns the hash of the evidence.
func
(
dve
*
DuplicateVoteEvidence
)
Hash
()
[]
byte
{
return
SimpleHashFromBinary
(
dve
)
}
// Verify returns an error if the two votes aren't conflicting.
// To be conflicting, they must be from the same validator, for the same H/R/S, but for different blocks.
func
(
dve
*
DuplicateVoteEvidence
)
Verify
(
chainID
string
)
error
{
// H/R/S must be the same
if
dve
.
VoteA
.
Height
!=
dve
.
VoteB
.
Height
||
dve
.
VoteA
.
Round
!=
dve
.
VoteB
.
Round
||
dve
.
VoteA
.
Type
!=
dve
.
VoteB
.
Type
{
return
fmt
.
Errorf
(
"DuplicateVoteEvidence Error: H/R/S does not match. Got %v and %v"
,
dve
.
VoteA
,
dve
.
VoteB
)
}
// Address must be the same
if
!
bytes
.
Equal
(
dve
.
VoteA
.
ValidatorAddress
,
dve
.
VoteB
.
ValidatorAddress
)
{
return
fmt
.
Errorf
(
"DuplicateVoteEvidence Error: Validator addresses do not match. Got %X and %X"
,
dve
.
VoteA
.
ValidatorAddress
,
dve
.
VoteB
.
ValidatorAddress
)
}
// XXX: Should we enforce index is the same ?
if
dve
.
VoteA
.
ValidatorIndex
!=
dve
.
VoteB
.
ValidatorIndex
{
return
fmt
.
Errorf
(
"DuplicateVoteEvidence Error: Validator indices do not match. Got %d and %d"
,
dve
.
VoteA
.
ValidatorIndex
,
dve
.
VoteB
.
ValidatorIndex
)
}
blockIDA
:=
BlockID
{
*
dve
.
VoteA
.
BlockID
,
}
blockIDB
:=
BlockID
{
*
dve
.
VoteB
.
BlockID
,
}
// BlockIDs must be different
if
blockIDA
.
Equals
(
blockIDB
)
{
return
fmt
.
Errorf
(
"DuplicateVoteEvidence Error: BlockIDs are the same (%v) - not a real duplicate vote"
,
dve
.
VoteA
.
BlockID
)
}
// Signatures must be valid
pubkey
,
err
:=
PubKeyFromString
(
dve
.
PubKey
)
if
err
!=
nil
{
return
fmt
.
Errorf
(
"DuplicateVoteEvidence Error: pubkey[%v] to PubKey failed:%v"
,
dve
.
PubKey
,
err
)
}
sigA
,
err
:=
ConsensusCrypto
.
SignatureFromBytes
(
dve
.
VoteA
.
Signature
)
if
err
!=
nil
{
return
fmt
.
Errorf
(
"DuplicateVoteEvidence Error: SIGA[%v] to signature failed:%v"
,
dve
.
VoteA
.
Signature
,
err
)
}
sigB
,
err
:=
ConsensusCrypto
.
SignatureFromBytes
(
dve
.
VoteB
.
Signature
)
if
err
!=
nil
{
return
fmt
.
Errorf
(
"DuplicateVoteEvidence Error: SIGB[%v] to signature failed:%v"
,
dve
.
VoteB
.
Signature
,
err
)
}
vote
:=
&
Vote
{
dve
.
VoteA
,
}
if
!
pubkey
.
VerifyBytes
(
SignBytes
(
chainID
,
vote
),
sigA
)
{
return
fmt
.
Errorf
(
"DuplicateVoteEvidence Error verifying VoteA: %v"
,
ErrVoteInvalidSignature
)
}
vote
=
&
Vote
{
dve
.
VoteB
,
}
if
!
pubkey
.
VerifyBytes
(
SignBytes
(
chainID
,
vote
),
sigB
)
{
return
fmt
.
Errorf
(
"DuplicateVoteEvidence Error verifying VoteB: %v"
,
ErrVoteInvalidSignature
)
}
return
nil
}
// Equal checks if two pieces of evidence are equal.
func
(
dve
*
DuplicateVoteEvidence
)
Equal
(
ev
Evidence
)
bool
{
if
_
,
ok
:=
ev
.
(
*
DuplicateVoteEvidence
);
!
ok
{
return
false
}
if
dve
==
nil
{
return
false
}
// just check their hashes
return
bytes
.
Equal
(
SimpleHashFromBinary
(
dve
),
SimpleHashFromBinary
(
ev
.
(
*
DuplicateVoteEvidence
)))
}
// TypeName ...
func
(
dve
*
DuplicateVoteEvidence
)
TypeName
()
string
{
return
DuplicateVote
}
// Copy ...
func
(
dve
*
DuplicateVoteEvidence
)
Copy
()
Evidence
{
return
&
DuplicateVoteEvidence
{}
}
// SetChild ...
func
(
dve
*
DuplicateVoteEvidence
)
SetChild
(
child
proto
.
Message
)
{
dve
.
DuplicateVoteEvidence
=
child
.
(
*
tmtypes
.
DuplicateVoteEvidence
)
}
// Child ...
func
(
dve
*
DuplicateVoteEvidence
)
Child
()
proto
.
Message
{
return
dve
.
DuplicateVoteEvidence
}
// SimpleHashFromBinary ...
func
SimpleHashFromBinary
(
item
*
DuplicateVoteEvidence
)
[]
byte
{
bytes
,
e
:=
json
.
Marshal
(
item
)
if
e
!=
nil
{
//commonlog.Error("SimpleHashFromBinary marshal failed", "type", item, "error", e)
panic
(
Fmt
(
"SimpleHashFromBinary marshal failed, err:%v"
,
e
))
}
return
crypto
.
Ripemd160
(
bytes
)
}
// EvidenceEnvelope2Evidence ...
func
EvidenceEnvelope2Evidence
(
envelope
*
tmtypes
.
EvidenceEnvelope
)
Evidence
{
if
v
,
ok
:=
EvidenceType2Type
[
envelope
.
TypeName
];
ok
{
realMsg2
:=
reflect
.
New
(
v
)
.
Interface
()
err
:=
proto
.
Unmarshal
(
envelope
.
Data
,
realMsg2
.
(
proto
.
Message
))
if
err
!=
nil
{
panic
(
Fmt
(
"Evidence is not valid"
,
"evidenceType"
,
envelope
.
TypeName
,
"err"
,
err
))
}
if
evidence
,
ok2
:=
EvidenceType2Obj
[
envelope
.
TypeName
];
ok2
{
evidence
=
evidence
.
Copy
()
evidence
.
SetChild
(
realMsg2
.
(
proto
.
Message
))
return
evidence
.
(
Evidence
)
}
}
return
nil
}
// MockGoodEvidence UNSTABLE
type
MockGoodEvidence
struct
{
MGHeight
int64
MGAddress
[]
byte
MGIndex
int
}
// NewMockGoodEvidence UNSTABLE
func
NewMockGoodEvidence
(
height
int64
,
index
int
,
address
[]
byte
)
MockGoodEvidence
{
return
MockGoodEvidence
{
height
,
address
,
index
}
}
// Height ...
func
(
e
MockGoodEvidence
)
Height
()
int64
{
return
e
.
MGHeight
}
// Address ...
func
(
e
MockGoodEvidence
)
Address
()
[]
byte
{
return
e
.
MGAddress
}
// Index ...
func
(
e
MockGoodEvidence
)
Index
()
int
{
return
e
.
MGIndex
}
// Hash ...
func
(
e
MockGoodEvidence
)
Hash
()
[]
byte
{
return
[]
byte
(
Fmt
(
"%d-%d"
,
e
.
MGHeight
,
e
.
MGIndex
))
}
// Verify ...
func
(
e
MockGoodEvidence
)
Verify
(
chainID
string
)
error
{
return
nil
}
// Equal ...
func
(
e
MockGoodEvidence
)
Equal
(
ev
Evidence
)
bool
{
e2
:=
ev
.
(
MockGoodEvidence
)
return
e
.
MGHeight
==
e2
.
MGHeight
&&
bytes
.
Equal
(
e
.
MGAddress
,
e2
.
MGAddress
)
&&
e
.
MGIndex
==
e2
.
MGIndex
}
func
(
e
MockGoodEvidence
)
String
()
string
{
return
Fmt
(
"GoodEvidence: %d/%s/%d"
,
e
.
MGHeight
,
e
.
MGAddress
,
e
.
MGIndex
)
}
// TypeName ...
func
(
e
MockGoodEvidence
)
TypeName
()
string
{
return
MockGood
}
// Copy ...
func
(
e
MockGoodEvidence
)
Copy
()
Evidence
{
return
&
MockGoodEvidence
{}
}
// SetChild ...
func
(
e
MockGoodEvidence
)
SetChild
(
proto
.
Message
)
{}
// Child ...
func
(
e
MockGoodEvidence
)
Child
()
proto
.
Message
{
return
nil
}
// MockBadEvidence UNSTABLE
type
MockBadEvidence
struct
{
MockGoodEvidence
}
// Verify ...
func
(
e
MockBadEvidence
)
Verify
(
chainID
string
)
error
{
return
fmt
.
Errorf
(
"MockBadEvidence"
)
}
// Equal ...
func
(
e
MockBadEvidence
)
Equal
(
ev
Evidence
)
bool
{
e2
:=
ev
.
(
MockBadEvidence
)
return
e
.
MGHeight
==
e2
.
MGHeight
&&
bytes
.
Equal
(
e
.
MGAddress
,
e2
.
MGAddress
)
&&
e
.
MGIndex
==
e2
.
MGIndex
}
func
(
e
MockBadEvidence
)
String
()
string
{
return
Fmt
(
"BadEvidence: %d/%s/%d"
,
e
.
MGHeight
,
e
.
MGAddress
,
e
.
MGIndex
)
}
// TypeName ...
func
(
e
MockBadEvidence
)
TypeName
()
string
{
return
MockBad
}
// Copy ...
func
(
e
MockBadEvidence
)
Copy
()
Evidence
{
return
&
MockBadEvidence
{}
}
// SetChild ...
func
(
e
MockBadEvidence
)
SetChild
(
proto
.
Message
)
{}
// Child ...
func
(
e
MockBadEvidence
)
Child
()
proto
.
Message
{
return
nil
}
//------------------------------------------------------
// evidence pool
// EvidencePool defines the EvidencePool interface used by the ConsensusState.
// UNSTABLE
type
EvidencePool
interface
{
PendingEvidence
()
[]
Evidence
AddEvidence
(
Evidence
)
error
Update
(
*
TendermintBlock
)
}
// MockEvidencePool is an empty implementation of a Mempool, useful for testing.
// UNSTABLE
type
MockEvidencePool
struct
{
}
// PendingEvidence ...
func
(
m
MockEvidencePool
)
PendingEvidence
()
[]
Evidence
{
return
nil
}
// AddEvidence ...
func
(
m
MockEvidencePool
)
AddEvidence
(
Evidence
)
error
{
return
nil
}
// Update ...
func
(
m
MockEvidencePool
)
Update
(
*
TendermintBlock
)
{}
plugin/consensus/tendermint/types/round_state.go
View file @
fceee563
...
...
@@ -32,7 +32,6 @@ const (
RoundStepCommit
=
RoundStepType
(
0x08
)
// Entered commit state machine
// NOTE: RoundStepNewHeight acts as RoundStepCommitWait.
EvidenceListID
=
byte
(
0x01
)
NewRoundStepID
=
byte
(
0x02
)
CommitStepID
=
byte
(
0x03
)
ProposalID
=
byte
(
0x04
)
...
...
@@ -52,7 +51,6 @@ const (
// InitMessageMap ...
func
InitMessageMap
()
{
MsgMap
=
map
[
byte
]
reflect
.
Type
{
EvidenceListID
:
reflect
.
TypeOf
(
tmtypes
.
EvidenceData
{}),
NewRoundStepID
:
reflect
.
TypeOf
(
tmtypes
.
NewRoundStepMsg
{}),
CommitStepID
:
reflect
.
TypeOf
(
tmtypes
.
CommitStepMsg
{}),
ProposalID
:
reflect
.
TypeOf
(
tmtypes
.
Proposal
{}),
...
...
plugin/consensus/tendermint/types/signable.go
View file @
fceee563
...
...
@@ -25,6 +25,7 @@ var (
ErrVoteInvalidSignature
=
errors
.
New
(
"Invalid signature"
)
ErrVoteInvalidBlockHash
=
errors
.
New
(
"Invalid block hash"
)
ErrVoteNonDeterministicSignature
=
errors
.
New
(
"Non-deterministic signature"
)
ErrVoteConflict
=
errors
.
New
(
"Conflicting vote"
)
ErrVoteNil
=
errors
.
New
(
"Nil vote"
)
votelog
=
log15
.
New
(
"module"
,
"tendermint-vote"
)
)
...
...
@@ -119,34 +120,6 @@ func (heartbeat *Heartbeat) WriteSignBytes(chainID string, w io.Writer, n *int,
*
err
=
writeErr
}
// ErrVoteConflictingVotes ...
type
ErrVoteConflictingVotes
struct
{
*
DuplicateVoteEvidence
}
func
(
err
*
ErrVoteConflictingVotes
)
Error
()
string
{
pubkey
,
error
:=
PubKeyFromString
(
err
.
PubKey
)
if
error
!=
nil
{
return
fmt
.
Sprintf
(
"Conflicting votes from validator PubKey:%v,error:%v"
,
err
.
PubKey
,
error
)
}
addr
:=
GenAddressByPubKey
(
pubkey
)
return
fmt
.
Sprintf
(
"Conflicting votes from validator %v"
,
addr
)
}
// NewConflictingVoteError ...
func
NewConflictingVoteError
(
val
*
Validator
,
voteA
,
voteB
*
tmtypes
.
Vote
)
*
ErrVoteConflictingVotes
{
keyString
:=
fmt
.
Sprintf
(
"%X"
,
val
.
PubKey
)
return
&
ErrVoteConflictingVotes
{
&
DuplicateVoteEvidence
{
&
tmtypes
.
DuplicateVoteEvidence
{
PubKey
:
keyString
,
VoteA
:
voteA
,
VoteB
:
voteB
,
},
},
}
}
// Types of votes
// TODO Make a new type "VoteType"
const
(
...
...
plugin/consensus/tendermint/types/vote_set.go
View file @
fceee563
...
...
@@ -200,7 +200,7 @@ func (voteSet *VoteSet) addVote(vote *Vote) (added bool, err error) {
// Add vote and get conflicting vote if any
added
,
conflicting
:=
voteSet
.
addVerifiedVote
(
vote
,
blockKey
,
val
.
VotingPower
)
if
conflicting
!=
nil
{
return
added
,
NewConflictingVoteError
(
val
,
conflicting
.
Vote
,
vote
.
V
ote
)
return
added
,
errors
.
Wrapf
(
ErrVoteConflict
,
"Conflicting vote: %v; New vote: %v"
,
conflicting
,
v
ote
)
}
if
!
added
{
PanicSanity
(
"Expected to add non-conflicting vote"
)
...
...
plugin/dapp/valnode/proto/tendermint.proto
View file @
fceee563
...
...
@@ -87,20 +87,6 @@ message State {
bytes
AppHash
=
12
;
}
message
DuplicateVoteEvidence
{
string
pubKey
=
1
;
Vote
voteA
=
2
;
Vote
voteB
=
3
;
}
message
EvidenceEnvelope
{
string
typeName
=
1
;
bytes
data
=
2
;
}
message
EvidenceData
{
repeated
EvidenceEnvelope
evidence
=
1
;
}
message
TendermintBlockHeader
{
string
chainID
=
1
;
...
...
@@ -115,14 +101,12 @@ message TendermintBlockHeader {
bytes
consensusHash
=
10
;
bytes
appHash
=
11
;
bytes
lastResultsHash
=
12
;
bytes
evidenceHash
=
13
;
bytes
proposerAddr
=
14
;
bytes
proposerAddr
=
13
;
}
message
TendermintBlock
{
TendermintBlockHeader
header
=
1
;
Block
data
=
2
;
EvidenceData
evidence
=
3
;
TendermintCommit
lastCommit
=
4
;
}
...
...
plugin/dapp/valnode/types/tendermint.pb.go
View file @
fceee563
...
...
@@ -22,9 +22,6 @@ It has these top-level messages:
Validator
ValidatorSet
State
DuplicateVoteEvidence
EvidenceEnvelope
EvidenceData
TendermintBlockHeader
TendermintBlock
Proposal
...
...
@@ -525,78 +522,6 @@ func (m *State) GetAppHash() []byte {
return
nil
}
type
DuplicateVoteEvidence
struct
{
PubKey
string
`protobuf:"bytes,1,opt,name=pubKey" json:"pubKey,omitempty"`
VoteA
*
Vote
`protobuf:"bytes,2,opt,name=voteA" json:"voteA,omitempty"`
VoteB
*
Vote
`protobuf:"bytes,3,opt,name=voteB" json:"voteB,omitempty"`
}
func
(
m
*
DuplicateVoteEvidence
)
Reset
()
{
*
m
=
DuplicateVoteEvidence
{}
}
func
(
m
*
DuplicateVoteEvidence
)
String
()
string
{
return
proto
.
CompactTextString
(
m
)
}
func
(
*
DuplicateVoteEvidence
)
ProtoMessage
()
{}
func
(
*
DuplicateVoteEvidence
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor0
,
[]
int
{
13
}
}
func
(
m
*
DuplicateVoteEvidence
)
GetPubKey
()
string
{
if
m
!=
nil
{
return
m
.
PubKey
}
return
""
}
func
(
m
*
DuplicateVoteEvidence
)
GetVoteA
()
*
Vote
{
if
m
!=
nil
{
return
m
.
VoteA
}
return
nil
}
func
(
m
*
DuplicateVoteEvidence
)
GetVoteB
()
*
Vote
{
if
m
!=
nil
{
return
m
.
VoteB
}
return
nil
}
type
EvidenceEnvelope
struct
{
TypeName
string
`protobuf:"bytes,1,opt,name=typeName" json:"typeName,omitempty"`
Data
[]
byte
`protobuf:"bytes,2,opt,name=data,proto3" json:"data,omitempty"`
}
func
(
m
*
EvidenceEnvelope
)
Reset
()
{
*
m
=
EvidenceEnvelope
{}
}
func
(
m
*
EvidenceEnvelope
)
String
()
string
{
return
proto
.
CompactTextString
(
m
)
}
func
(
*
EvidenceEnvelope
)
ProtoMessage
()
{}
func
(
*
EvidenceEnvelope
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor0
,
[]
int
{
14
}
}
func
(
m
*
EvidenceEnvelope
)
GetTypeName
()
string
{
if
m
!=
nil
{
return
m
.
TypeName
}
return
""
}
func
(
m
*
EvidenceEnvelope
)
GetData
()
[]
byte
{
if
m
!=
nil
{
return
m
.
Data
}
return
nil
}
type
EvidenceData
struct
{
Evidence
[]
*
EvidenceEnvelope
`protobuf:"bytes,1,rep,name=evidence" json:"evidence,omitempty"`
}
func
(
m
*
EvidenceData
)
Reset
()
{
*
m
=
EvidenceData
{}
}
func
(
m
*
EvidenceData
)
String
()
string
{
return
proto
.
CompactTextString
(
m
)
}
func
(
*
EvidenceData
)
ProtoMessage
()
{}
func
(
*
EvidenceData
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor0
,
[]
int
{
15
}
}
func
(
m
*
EvidenceData
)
GetEvidence
()
[]
*
EvidenceEnvelope
{
if
m
!=
nil
{
return
m
.
Evidence
}
return
nil
}
type
TendermintBlockHeader
struct
{
ChainID
string
`protobuf:"bytes,1,opt,name=chainID" json:"chainID,omitempty"`
Height
int64
`protobuf:"varint,2,opt,name=height" json:"height,omitempty"`
...
...
@@ -610,14 +535,13 @@ type TendermintBlockHeader struct {
ConsensusHash
[]
byte
`protobuf:"bytes,10,opt,name=consensusHash,proto3" json:"consensusHash,omitempty"`
AppHash
[]
byte
`protobuf:"bytes,11,opt,name=appHash,proto3" json:"appHash,omitempty"`
LastResultsHash
[]
byte
`protobuf:"bytes,12,opt,name=lastResultsHash,proto3" json:"lastResultsHash,omitempty"`
EvidenceHash
[]
byte
`protobuf:"bytes,13,opt,name=evidenceHash,proto3" json:"evidenceHash,omitempty"`
ProposerAddr
[]
byte
`protobuf:"bytes,14,opt,name=proposerAddr,proto3" json:"proposerAddr,omitempty"`
ProposerAddr
[]
byte
`protobuf:"bytes,13,opt,name=proposerAddr,proto3" json:"proposerAddr,omitempty"`
}
func
(
m
*
TendermintBlockHeader
)
Reset
()
{
*
m
=
TendermintBlockHeader
{}
}
func
(
m
*
TendermintBlockHeader
)
String
()
string
{
return
proto
.
CompactTextString
(
m
)
}
func
(
*
TendermintBlockHeader
)
ProtoMessage
()
{}
func
(
*
TendermintBlockHeader
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor0
,
[]
int
{
1
6
}
}
func
(
*
TendermintBlockHeader
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor0
,
[]
int
{
1
3
}
}
func
(
m
*
TendermintBlockHeader
)
GetChainID
()
string
{
if
m
!=
nil
{
...
...
@@ -703,13 +627,6 @@ func (m *TendermintBlockHeader) GetLastResultsHash() []byte {
return
nil
}
func
(
m
*
TendermintBlockHeader
)
GetEvidenceHash
()
[]
byte
{
if
m
!=
nil
{
return
m
.
EvidenceHash
}
return
nil
}
func
(
m
*
TendermintBlockHeader
)
GetProposerAddr
()
[]
byte
{
if
m
!=
nil
{
return
m
.
ProposerAddr
...
...
@@ -720,14 +637,13 @@ func (m *TendermintBlockHeader) GetProposerAddr() []byte {
type
TendermintBlock
struct
{
Header
*
TendermintBlockHeader
`protobuf:"bytes,1,opt,name=header" json:"header,omitempty"`
Data
*
types3
.
Block
`protobuf:"bytes,2,opt,name=data" json:"data,omitempty"`
Evidence
*
EvidenceData
`protobuf:"bytes,3,opt,name=evidence" json:"evidence,omitempty"`
LastCommit
*
TendermintCommit
`protobuf:"bytes,4,opt,name=lastCommit" json:"lastCommit,omitempty"`
}
func
(
m
*
TendermintBlock
)
Reset
()
{
*
m
=
TendermintBlock
{}
}
func
(
m
*
TendermintBlock
)
String
()
string
{
return
proto
.
CompactTextString
(
m
)
}
func
(
*
TendermintBlock
)
ProtoMessage
()
{}
func
(
*
TendermintBlock
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor0
,
[]
int
{
1
7
}
}
func
(
*
TendermintBlock
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor0
,
[]
int
{
1
4
}
}
func
(
m
*
TendermintBlock
)
GetHeader
()
*
TendermintBlockHeader
{
if
m
!=
nil
{
...
...
@@ -743,13 +659,6 @@ func (m *TendermintBlock) GetData() *types3.Block {
return
nil
}
func
(
m
*
TendermintBlock
)
GetEvidence
()
*
EvidenceData
{
if
m
!=
nil
{
return
m
.
Evidence
}
return
nil
}
func
(
m
*
TendermintBlock
)
GetLastCommit
()
*
TendermintCommit
{
if
m
!=
nil
{
return
m
.
LastCommit
...
...
@@ -770,7 +679,7 @@ type Proposal struct {
func
(
m
*
Proposal
)
Reset
()
{
*
m
=
Proposal
{}
}
func
(
m
*
Proposal
)
String
()
string
{
return
proto
.
CompactTextString
(
m
)
}
func
(
*
Proposal
)
ProtoMessage
()
{}
func
(
*
Proposal
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor0
,
[]
int
{
1
8
}
}
func
(
*
Proposal
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor0
,
[]
int
{
1
5
}
}
func
(
m
*
Proposal
)
GetHeight
()
int64
{
if
m
!=
nil
{
...
...
@@ -832,7 +741,7 @@ type NewRoundStepMsg struct {
func
(
m
*
NewRoundStepMsg
)
Reset
()
{
*
m
=
NewRoundStepMsg
{}
}
func
(
m
*
NewRoundStepMsg
)
String
()
string
{
return
proto
.
CompactTextString
(
m
)
}
func
(
*
NewRoundStepMsg
)
ProtoMessage
()
{}
func
(
*
NewRoundStepMsg
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor0
,
[]
int
{
1
9
}
}
func
(
*
NewRoundStepMsg
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor0
,
[]
int
{
1
6
}
}
func
(
m
*
NewRoundStepMsg
)
GetHeight
()
int64
{
if
m
!=
nil
{
...
...
@@ -879,7 +788,7 @@ type ValidBlockMsg struct {
func
(
m
*
ValidBlockMsg
)
Reset
()
{
*
m
=
ValidBlockMsg
{}
}
func
(
m
*
ValidBlockMsg
)
String
()
string
{
return
proto
.
CompactTextString
(
m
)
}
func
(
*
ValidBlockMsg
)
ProtoMessage
()
{}
func
(
*
ValidBlockMsg
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor0
,
[]
int
{
20
}
}
func
(
*
ValidBlockMsg
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor0
,
[]
int
{
17
}
}
func
(
m
*
ValidBlockMsg
)
GetHeight
()
int64
{
if
m
!=
nil
{
...
...
@@ -916,7 +825,7 @@ type CommitStepMsg struct {
func
(
m
*
CommitStepMsg
)
Reset
()
{
*
m
=
CommitStepMsg
{}
}
func
(
m
*
CommitStepMsg
)
String
()
string
{
return
proto
.
CompactTextString
(
m
)
}
func
(
*
CommitStepMsg
)
ProtoMessage
()
{}
func
(
*
CommitStepMsg
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor0
,
[]
int
{
21
}
}
func
(
*
CommitStepMsg
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor0
,
[]
int
{
18
}
}
func
(
m
*
CommitStepMsg
)
GetHeight
()
int64
{
if
m
!=
nil
{
...
...
@@ -934,7 +843,7 @@ type ProposalPOLMsg struct {
func
(
m
*
ProposalPOLMsg
)
Reset
()
{
*
m
=
ProposalPOLMsg
{}
}
func
(
m
*
ProposalPOLMsg
)
String
()
string
{
return
proto
.
CompactTextString
(
m
)
}
func
(
*
ProposalPOLMsg
)
ProtoMessage
()
{}
func
(
*
ProposalPOLMsg
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor0
,
[]
int
{
22
}
}
func
(
*
ProposalPOLMsg
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor0
,
[]
int
{
19
}
}
func
(
m
*
ProposalPOLMsg
)
GetHeight
()
int64
{
if
m
!=
nil
{
...
...
@@ -967,7 +876,7 @@ type HasVoteMsg struct {
func
(
m
*
HasVoteMsg
)
Reset
()
{
*
m
=
HasVoteMsg
{}
}
func
(
m
*
HasVoteMsg
)
String
()
string
{
return
proto
.
CompactTextString
(
m
)
}
func
(
*
HasVoteMsg
)
ProtoMessage
()
{}
func
(
*
HasVoteMsg
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor0
,
[]
int
{
2
3
}
}
func
(
*
HasVoteMsg
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor0
,
[]
int
{
2
0
}
}
func
(
m
*
HasVoteMsg
)
GetHeight
()
int64
{
if
m
!=
nil
{
...
...
@@ -1007,7 +916,7 @@ type VoteSetMaj23Msg struct {
func
(
m
*
VoteSetMaj23Msg
)
Reset
()
{
*
m
=
VoteSetMaj23Msg
{}
}
func
(
m
*
VoteSetMaj23Msg
)
String
()
string
{
return
proto
.
CompactTextString
(
m
)
}
func
(
*
VoteSetMaj23Msg
)
ProtoMessage
()
{}
func
(
*
VoteSetMaj23Msg
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor0
,
[]
int
{
2
4
}
}
func
(
*
VoteSetMaj23Msg
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor0
,
[]
int
{
2
1
}
}
func
(
m
*
VoteSetMaj23Msg
)
GetHeight
()
int64
{
if
m
!=
nil
{
...
...
@@ -1048,7 +957,7 @@ type VoteSetBitsMsg struct {
func
(
m
*
VoteSetBitsMsg
)
Reset
()
{
*
m
=
VoteSetBitsMsg
{}
}
func
(
m
*
VoteSetBitsMsg
)
String
()
string
{
return
proto
.
CompactTextString
(
m
)
}
func
(
*
VoteSetBitsMsg
)
ProtoMessage
()
{}
func
(
*
VoteSetBitsMsg
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor0
,
[]
int
{
2
5
}
}
func
(
*
VoteSetBitsMsg
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor0
,
[]
int
{
2
2
}
}
func
(
m
*
VoteSetBitsMsg
)
GetHeight
()
int64
{
if
m
!=
nil
{
...
...
@@ -1097,7 +1006,7 @@ type Heartbeat struct {
func
(
m
*
Heartbeat
)
Reset
()
{
*
m
=
Heartbeat
{}
}
func
(
m
*
Heartbeat
)
String
()
string
{
return
proto
.
CompactTextString
(
m
)
}
func
(
*
Heartbeat
)
ProtoMessage
()
{}
func
(
*
Heartbeat
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor0
,
[]
int
{
2
6
}
}
func
(
*
Heartbeat
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor0
,
[]
int
{
2
3
}
}
func
(
m
*
Heartbeat
)
GetValidatorAddress
()
[]
byte
{
if
m
!=
nil
{
...
...
@@ -1148,7 +1057,7 @@ type IsHealthy struct {
func
(
m
*
IsHealthy
)
Reset
()
{
*
m
=
IsHealthy
{}
}
func
(
m
*
IsHealthy
)
String
()
string
{
return
proto
.
CompactTextString
(
m
)
}
func
(
*
IsHealthy
)
ProtoMessage
()
{}
func
(
*
IsHealthy
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor0
,
[]
int
{
2
7
}
}
func
(
*
IsHealthy
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor0
,
[]
int
{
2
4
}
}
func
(
m
*
IsHealthy
)
GetIsHealthy
()
bool
{
if
m
!=
nil
{
...
...
@@ -1171,9 +1080,6 @@ func init() {
proto
.
RegisterType
((
*
Validator
)(
nil
),
"types.Validator"
)
proto
.
RegisterType
((
*
ValidatorSet
)(
nil
),
"types.ValidatorSet"
)
proto
.
RegisterType
((
*
State
)(
nil
),
"types.State"
)
proto
.
RegisterType
((
*
DuplicateVoteEvidence
)(
nil
),
"types.DuplicateVoteEvidence"
)
proto
.
RegisterType
((
*
EvidenceEnvelope
)(
nil
),
"types.EvidenceEnvelope"
)
proto
.
RegisterType
((
*
EvidenceData
)(
nil
),
"types.EvidenceData"
)
proto
.
RegisterType
((
*
TendermintBlockHeader
)(
nil
),
"types.TendermintBlockHeader"
)
proto
.
RegisterType
((
*
TendermintBlock
)(
nil
),
"types.TendermintBlock"
)
proto
.
RegisterType
((
*
Proposal
)(
nil
),
"types.Proposal"
)
...
...
@@ -1191,97 +1097,89 @@ func init() {
func
init
()
{
proto
.
RegisterFile
(
"tendermint.proto"
,
fileDescriptor0
)
}
var
fileDescriptor0
=
[]
byte
{
// 1460 bytes of a gzipped FileDescriptorProto
0x1f
,
0x8b
,
0x08
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x02
,
0xff
,
0xbc
,
0x58
,
0xdd
,
0x6e
,
0x1b
,
0xb7
,
0x12
,
0xc6
,
0x5a
,
0x3f
,
0x96
,
0x46
,
0xb2
,
0x2c
,
0x30
,
0xc7
,
0x89
,
0x4e
,
0x8e
,
0x0f
,
0xa0
,
0x12
,
0xfd
,
0x51
,
0x93
,
0xc0
,
0x09
,
0xec
,
0x00
,
0xbd
,
0x48
,
0x53
,
0xc4
,
0xb2
,
0x83
,
0xd8
,
0xad
,
0x9d
,
0x08
,
0x94
,
0x90
,
0x5e
,
0xd3
,
0x12
,
0x2b
,
0x6d
,
0x2b
,
0xed
,
0x6e
,
0x97
,
0x94
,
0x62
,
0x17
,
0xe8
,
0x4d
,
0xdf
,
0xa0
,
0x40
,
0x5f
,
0xa3
,
0x57
,
0x7d
,
0x88
,
0x3e
,
0x40
,
0xd1
,
0xab
,
0xa2
,
0x7d
,
0x96
,
0x82
,
0x43
,
0xee
,
0x8a
,
0xbb
,
0x52
,
0x9c
,
0xa6
,
0x28
,
0x7a
,
0xa7
,
0xf9
,
0xf8
,
0x91
,
0x43
,
0xce
,
0x7c
,
0x33
,
0xe4
,
0x0a
,
0x9a
,
0x4a
,
0x04
,
0x23
,
0x11
,
0xcf
,
0xfc
,
0x40
,
0xed
,
0x45
,
0x71
,
0xa8
,
0x42
,
0x52
,
0x52
,
0x57
,
0x91
,
0x90
,
0xb7
,
0x9b
,
0x17
,
0xd3
,
0x70
,
0xf8
,
0xd5
,
0x70
,
0xc2
,
0xfd
,
0xc0
,
0x0c
,
0xd0
,
0xff
,
0xc3
,
0x66
,
0x57
,
0x63
,
0xa7
,
0xc7
,
0x84
,
0x40
,
0xf1
,
0x84
,
0xcb
,
0x49
,
0xcb
,
0x6b
,
0x7b
,
0x9d
,
0x3a
,
0xc3
,
0xdf
,
0xf4
,
0x13
,
0x20
,
0x83
,
0x74
,
0xad
,
0xae
,
0xaf
,
0x0e
,
0xe3
,
0x98
,
0x5f
,
0x69
,
0x66
,
0xd7
,
0x57
,
0x12
,
0x99
,
0x25
,
0x86
,
0xbf
,
0xc9
,
0x7f
,
0xa0
,
0xf4
,
0x74
,
0x2a
,
0x66
,
0xb2
,
0xb5
,
0xd1
,
0x2e
,
0x74
,
0x8a
,
0xcc
,
0x18
,
0xf4
,
0xbb
,
0x0d
,
0x28
,
0xbe
,
0x0c
,
0x95
,
0x20
,
0x77
,
0xa0
,
0xf9
,
0x92
,
0x4f
,
0xfd
,
0x11
,
0x57
,
0x61
,
0x7c
,
0x38
,
0x1a
,
0xc5
,
0x42
,
0x4a
,
0xeb
,
0x68
,
0x05
,
0x27
,
0xef
,
0x43
,
0x23
,
0xc5
,
0x4e
,
0x83
,
0x91
,
0xb8
,
0x6c
,
0x6d
,
0xa0
,
0xa3
,
0x1c
,
0x4a
,
0x6e
,
0x42
,
0xf9
,
0x44
,
0xf8
,
0xe3
,
0x89
,
0x6a
,
0x15
,
0xda
,
0x5e
,
0xa7
,
0xc0
,
0xac
,
0xa5
,
0xb7
,
0xc2
,
0xc2
,
0x79
,
0x30
,
0x6a
,
0x15
,
0x71
,
0x9a
,
0x31
,
0xc8
,
0x2e
,
0x54
,
0x07
,
0xfe
,
0x4c
,
0x48
,
0xc5
,
0x67
,
0x51
,
0xab
,
0x84
,
0x13
,
0x96
,
0x80
,
0x3e
,
0xd2
,
0xe0
,
0x2a
,
0x12
,
0xad
,
0x72
,
0xdb
,
0xeb
,
0x6c
,
0x31
,
0xfc
,
0x4d
,
0x3a
,
0x69
,
0x6c
,
0x5a
,
0x9b
,
0x6d
,
0xaf
,
0x53
,
0xdb
,
0x6f
,
0xec
,
0x61
,
0x18
,
0xf7
,
0x2c
,
0xca
,
0xd2
,
0xd0
,
0xed
,
0x42
,
0xb5
,
0xef
,
0x8f
,
0x03
,
0xae
,
0xe6
,
0xb1
,
0x68
,
0x55
,
0xf0
,
0x58
,
0x4b
,
0x80
,
0xfa
,
0xd0
,
0x5c
,
0x06
,
0xf1
,
0x28
,
0x9c
,
0xcd
,
0x7c
,
0xe5
,
0xae
,
0xed
,
0x5d
,
0xbf
,
0xf6
,
0x5d
,
0x80
,
0x5e
,
0x2c
,
0x86
,
0x38
,
0xcd
,
0x44
,
0xb7
,
0xb6
,
0x5f
,
0xb3
,
0x64
,
0x1d
,
0x5a
,
0xe6
,
0x0c
,
0xd3
,
0x1f
,
0x3c
,
0xb8
,
0xe1
,
0x24
,
0x0c
,
0x97
,
0x08
,
0xbe
,
0x08
,
0x09
,
0x85
,
0x52
,
0x5f
,
0x71
,
0x25
,
0x30
,
0x92
,
0xb5
,
0xfd
,
0xba
,
0x9d
,
0x8f
,
0x18
,
0x33
,
0x43
,
0xe4
,
0x2e
,
0x54
,
0x7a
,
0x71
,
0x18
,
0x85
,
0x92
,
0x4f
,
0x31
,
0xa0
,
0xb5
,
0xfd
,
0x6d
,
0x4b
,
0x4b
,
0x60
,
0x96
,
0x12
,
0xc8
,
0x3d
,
0x28
,
0xa1
,
0x96
,
0x30
,
0xc6
,
0xb5
,
0xfd
,
0x9b
,
0x96
,
0x99
,
0xf3
,
0xcd
,
0x0c
,
0x89
,
0x7e
,
0x0e
,
0x55
,
0xb4
,
0xfb
,
0xfe
,
0x37
,
0x82
,
0xdc
,
0x86
,
0xca
,
0x39
,
0xbf
,
0xec
,
0x5e
,
0x29
,
0x91
,
0x28
,
0x28
,
0xb5
,
0x75
,
0x4a
,
0xcf
,
0xf9
,
0xe5
,
0xe0
,
0x52
,
0xda
,
0x94
,
0x5b
,
0xcb
,
0xe2
,
0xcf
,
0xb8
,
0x4c
,
0x52
,
0x6d
,
0x2c
,
0xfa
,
0x31
,
0x94
,
0x07
,
0x97
,
0x7f
,
0x71
,
0x55
,
0x3d
,
0x7b
,
0x23
,
0x33
,
0xfb
,
0x31
,
0xd4
,
0x70
,
0x5b
,
0xcf
,
0x42
,
0x29
,
0xfd
,
0x88
,
0xec
,
0x01
,
0x41
,
0xb3
,
0xc7
,
0x63
,
0xa5
,
0xd7
,
0x74
,
0x17
,
0x5b
,
0x33
,
0x42
,
0x3b
,
0xd0
,
0x78
,
0xba
,
0xf0
,
0x47
,
0x22
,
0x18
,
0x8a
,
0x1e
,
0x8f
,
0xf9
,
0x2c
,
0x71
,
0x74
,
0x38
,
0x16
,
0x38
,
0xcb
,
0x38
,
0x3a
,
0x1c
,
0x0b
,
0xfa
,
0xbb
,
0x07
,
0xdb
,
0x47
,
0x61
,
0x20
,
0x45
,
0x20
,
0xe7
,
0xd2
,
0x72
,
0xf7
,
0x9c
,
0x98
,
0x58
,
0x0d
,
0x34
,
0x5d
,
0x0d
,
0x68
,
0x9c
,
0x39
,
0x61
,
0x7b
,
0x2f
,
0x39
,
0xaa
,
0xcd
,
0xe1
,
0x56
,
0x12
,
0x72
,
0x04
,
0x59
,
0x12
,
0x87
,
0x87
,
0x99
,
0x33
,
0xd9
,
0x44
,
0x12
,
0x77
,
0x61
,
0x33
,
0xc2
,
0x32
,
0x47
,
0x7f
,
0x9c
,
0x3f
,
0x8a
,
0xcd
,
0xeb
,
0x8e
,
0x9d
,
0x98
,
0x1d
,
0x64
,
0x39
,
0x32
,
0x9d
,
0x43
,
0x35
,
0xad
,
0x4d
,
0xd2
,
0x82
,
0xcd
,
0x6c
,
0x85
,
0x27
,
0xa6
,
0x0e
,
0x4f
,
0x6f
,
0x7e
,
0xf1
,
0x99
,
0xb8
,
0xc2
,
0x23
,
0xd4
,
0x99
,
0xb5
,
0x48
,
0x1b
,
0x6a
,
0x2f
,
0x43
,
0xe5
,
0x07
,
0xe3
,
0x5e
,
0xf8
,
0x4a
,
0xc4
,
0x36
,
0xc5
,
0x2e
,
0xa4
,
0x4b
,
0xfa
,
0x70
,
0x38
,
0x9c
,
0xcf
,
0x70
,
0x5b
,
0x05
,
0x66
,
0x0c
,
0x1a
,
0x40
,
0x3d
,
0x75
,
0xdb
,
0x17
,
0x8a
,
0x3c
,
0x00
,
0x48
,
0x6d
,
0xed
,
0xbc
,
0xe0
,
0xc4
,
0x34
,
0x1d
,
0x60
,
0x0e
,
0x87
,
0xdc
,
0x4b
,
0x34
,
0x2f
,
0x62
,
0x1b
,
0xd6
,
0x55
,
0x7e
,
0xca
,
0xa0
,
0xbf
,
0x16
,
0x6d
,
0x19
,
0xe9
,
0x33
,
0x1e
,
0xe9
,
0x2e
,
0x6a
,
0xcb
,
0xb7
,
0xca
,
0x12
,
0x93
,
0x74
,
0x60
,
0xfb
,
0x8c
,
0x4b
,
0x23
,
0x7f
,
0xdb
,
0x9d
,
0x8c
,
0xe8
,
0xf2
,
0xb0
,
0x6e
,
0x89
,
0x29
,
0x34
,
0x08
,
0x15
,
0x9f
,
0x0e
,
0x2e
,
0xed
,
0xd1
,
0x57
,
0x70
,
0xf2
,
0x00
,
0x6a
,
0x29
,
0x76
,
0x7a
,
0x6c
,
0x93
,
0x93
,
0x6f
,
0x19
,
0x2e
,
0x85
,
0xbc
,
0x0b
,
0x5b
,
0xcb
,
0x55
,
0xfc
,
0x99
,
0xb0
,
0x2d
,
0x2f
,
0x0b
,
0x92
,
0x83
,
0x4c
,
0xc4
,
0xca
,
0xb8
,
0xec
,
0x8d
,
0x7c
,
0x04
,
0xfa
,
0x42
,
0x65
,
0x82
,
0xf6
,
0x08
,
0x1a
,
0x7a
,
0x15
,
0x67
,
0xe2
,
0xe6
,
0xeb
,
0x27
,
0xe6
,
0xa8
,
0xe4
,
0x09
,
0xfc
,
0x4f
,
0x23
,
0x26
,
0x06
,
0x4b
,
0xfc
,
0x68
,
0xc2
,
0x83
,
0xb1
,
0x18
,
0x61
,
0xf3
,
0x2c
,
0xb0
,
0xeb
,
0x28
,
0xe4
,
0xc9
,
0x4a
,
0x2d
,
0xb5
,
0xaa
,
0x99
,
0x26
,
0x94
,
0x1b
,
0x65
,
0x2b
,
0xa5
,
0xf7
,
0x29
,
0xb4
,
0x97
,
0x0e
,
0x72
,
0x83
,
0xc9
,
0x46
,
0x00
,
0x37
,
0xf2
,
0x46
,
0x5e
,
0x92
,
0x6f
,
0x26
,
0xe4
,
0x7c
,
0xaa
,
0x24
,
0x5e
,
0xa0
,
0x35
,
0x14
,
0x77
,
0x1e
,
0xc6
,
0xba
,
0x88
,
0x22
,
0x64
,
0xd4
,
0x6d
,
0x5d
,
0x18
,
0x93
,
0xce
,
0x61
,
0xe7
,
0x78
,
0x1e
,
0x4d
,
0xfd
,
0x21
,
0x57
,
0x42
,
0xb7
,
0xf4
,
0xa4
,
0xba
,
0x74
,
0xc1
,
0x44
,
0xa6
,
0x60
,
0x8c
,
0xca
,
0xac
,
0x45
,
0xde
,
0x81
,
0xd2
,
0x22
,
0x54
,
0xe2
,
0xd0
,
0x6a
,
0x36
,
0x73
,
0x1d
,
0x98
,
0x91
,
0x84
,
0xd2
,
0xb5
,
0x1d
,
0x60
,
0x95
,
0xd2
,
0xa5
,
0x5d
,
0x68
,
0x26
,
0x9e
,
0x9e
,
0x06
,
0x0b
,
0x31
,
0x0d
,
0x23
,
0x6c
,
0xa3
,
0x9a
,
0xf8
,
0x9c
,
0xcf
,
0x84
,
0xf5
,
0x99
,
0xda
,
0xfa
,
0x8e
,
0x1c
,
0x71
,
0xc5
,
0x6d
,
0xf1
,
0xe2
,
0x6f
,
0x7a
,
0x04
,
0xf5
,
0x64
,
0x8d
,
0x63
,
0xae
,
0x38
,
0x39
,
0x80
,
0x8a
,
0xb0
,
0xb6
,
0x2d
,
0xc0
,
0x5b
,
0xb9
,
0x16
,
0x92
,
0xb8
,
0x62
,
0x29
,
0x91
,
0xfe
,
0x56
,
0x80
,
0x9d
,
0xdc
,
0xcd
,
0x71
,
0x22
,
0xf8
,
0x48
,
0x60
,
0x2f
,
0x19
,
0x66
,
0xeb
,
0xcc
,
0x9a
,
0x3a
,
0x34
,
0x13
,
0xb7
,
0xbc
,
0xac
,
0xa5
,
0x3b
,
0x45
,
0x8c
,
0x97
,
0xbf
,
0x29
,
0x25
,
0x63
,
0xe8
,
0xad
,
0x2b
,
0x5d
,
0x04
,
0xa6
,
0x7d
,
0xe0
,
0x6f
,
0xbd
,
0x42
,
0x30
,
0x9f
,
0xe9
,
0xbb
,
0xc6
,
0x94
,
0x86
,
0xb5
,
0x74
,
0xad
,
0x4d
,
0x9d
,
0x5a
,
0x2b
,
0xaf
,
0xaf
,
0x35
,
0x87
,
0x82
,
0x41
,
0x33
,
0x85
,
0x6a
,
0x4a
,
0xa1
,
0xc0
,
0x52
,
0x5b
,
0x3f
,
0x66
,
0x34
,
0xd5
,
0x5c
,
0xfb
,
0x98
,
0x7c
,
0xf3
,
0x3e
,
0xc8
,
0xa1
,
0x9a
,
0xb7
,
0x48
,
0xa5
,
0x8e
,
0xbc
,
0xaa
,
0xe1
,
0x65
,
0x51
,
0x5d
,
0xd7
,
0xc3
,
0x44
,
0x89
,
0x48
,
0x03
,
0xa4
,
0x65
,
0x41
,
0x1d
,
0x37
,
0x6e
,
0xb5
,
0x66
,
0xd4
,
0x98
,
0x98
,
0x5a
,
0xaf
,
0xd3
,
0x9c
,
0x5e
,
0x8d
,
0x1a
,
0xf3
,
0x30
,
0xa1
,
0x50
,
0x4f
,
0x32
,
0x84
,
0xb4
,
0x2d
,
0xa4
,
0x65
,
0x30
,
0xcd
,
0x89
,
0x6c
,
0x77
,
0xd4
,
0x4d
,
0xbe
,
0xd5
,
0x30
,
0x1c
,
0x17
,
0xa3
,
0xbf
,
0x78
,
0xb0
,
0x9d
,
0xcb
,
0x2e
,
0x79
,
0xa8
,
0xb3
,
0xa7
,
0x33
,
0x6c
,
0x6f
,
0xbe
,
0xdd
,
0xf5
,
0xef
,
0x07
,
0xa3
,
0x02
,
0x66
,
0xb9
,
0xa4
,
0xed
,
0x08
,
0x70
,
0xf9
,
0x88
,
0x31
,
0x2f
,
0x0d
,
0x1c
,
0x21
,
0xf7
,
0x1d
,
0xf9
,
0x15
,
0x32
,
0x4d
,
0xc9
,
0x55
,
0xe9
,
0x52
,
0x7a
,
0xe4
,
0x23
,
0x80
,
0x65
,
0x22
,
0x6c
,
0x5f
,
0xbd
,
0xb5
,
0xb2
,
0x19
,
0x33
,
0xcc
,
0x1c
,
0x2a
,
0xfd
,
0xc3
,
0x5b
,
0x3e
,
0x97
,
0x1c
,
0x31
,
0x7a
,
0xeb
,
0xc5
,
0x68
,
0x5e
,
0x33
,
0x56
,
0x8c
,
0xbb
,
0x50
,
0x55
,
0xe9
,
0x4b
,
0xd4
,
0xc8
,
0x74
,
0x09
,
0x68
,
0x31
,
0xf5
,
0x5e
,
0x9c
,
0xb9
,
0x0f
,
0xd8
,
0xd4
,
0x26
,
0x7b
,
0x00
,
0xbd
,
0x17
,
0x67
,
0x89
,
0x32
,
0x4b
,
0x6b
,
0x95
,
0xe9
,
0x30
,
0xb4
,
0x27
,
0x99
,
0xbe
,
0x4b
,
0xcb
,
0xe6
,
0x5d
,
0x9a
,
0x02
,
0x7a
,
0x14
,
0x9f
,
0x67
,
0x13
,
0x9d
,
0xdd
,
0x4d
,
0x33
,
0x9a
,
0x02
,
0xf4
,
0x27
,
0x0f
,
0xb6
,
0x9f
,
0x8b
,
0x57
,
0xe8
,
0xb8
,
0xaf
,
0x44
,
0x74
,
0x2e
,
0xc7
,
0x6f
,
0x79
,
0x4e
,
0x02
,
0x45
,
0xa9
,
0x84
,
0x39
,
0x62
,
0x89
,
0xe1
,
0x6f
,
0xf2
,
0x10
,
0x76
,
0xa4
,
0x18
,
0x86
,
0xc1
,
0x48
,
0xf6
,
0xfd
,
0x60
,
0x28
,
0xfa
,
0x8a
,
0xc7
,
0x6a
,
0x90
,
0x54
,
0x66
,
0x89
,
0xad
,
0x1f
,
0x4c
,
0x44
,
0x6b
,
0xd3
,
0x80
,
0x9e
,
0x4a
,
0xc8
,
0xcf
,
0xc3
,
0xf4
,
0x15
,
0x6c
,
0xe1
,
0x8d
,
0x81
,
0x11
,
0x78
,
0xfb
,
0x2d
,
0x67
,
0x42
,
0x52
,
0xc8
,
0x85
,
0x44
,
0xa7
,
0xc6
,
0x97
,
0x8e
,
0x54
,
0x2a
,
0x2c
,
0xb5
,
0xe9
,
0x07
,
0xb0
,
0x65
,
0x7e
,
0xbd
,
0x21
,
0x56
,
0xf4
,
0x7b
,
0x0f
,
0x1a
,
0x89
,
0x70
,
0x7a
,
0x2f
,
0xce
,
0xae
,
0xdb
,
0xe3
,
0x1d
,
0x68
,
0x46
,
0x4b
,
0x26
,
0x73
,
0xb6
,
0xbb
,
0x82
,
0x93
,
0x47
,
0x50
,
0x73
,
0x30
,
0x2b
,
0xfe
,
0xff
,
0xae
,
0x96
,
0x95
,
0xfd
,
0x86
,
0x63
,
0x2e
,
0x9b
,
0x8e
,
0x00
,
0x4e
,
0xb8
,
0xd4
,
0x77
,
0xc3
,
0xdf
,
0xca
,
0xb2
,
0x76
,
0x92
,
0x64
,
0x59
,
0xff
,
0xd6
,
0x4c
,
0x1f
,
0x3f
,
0xdc
,
0xec
,
0x17
,
0x18
,
0x1a
,
0xf4
,
0x5b
,
0xd8
,
0xd6
,
0x2e
,
0xfa
,
0x42
,
0x9d
,
0xf3
,
0x2f
,
0xf7
,
0x0f
,
0xfe
,
0x19
,
0x57
,
0x1d
,
0xd8
,
0xbc
,
0xb8
,
0xf6
,
0x55
,
0x94
,
0x0c
,
0xd3
,
0x1f
,
0x3d
,
0x68
,
0x58
,
0xff
,
0xfa
,
0x8b
,
0xf5
,
0x5f
,
0x76
,
0x4f
,
0xee
,
0x9b
,
0x0b
,
0x59
,
0xda
,
0xb2
,
0xbd
,
0x26
,
0x35
,
0x86
,
0x47
,
0x7f
,
0xf6
,
0xa0
,
0x7a
,
0x22
,
0x78
,
0xac
,
0x2e
,
0x04
,
0x47
,
0x2d
,
0x2c
,
0x5e
,
0xf3
,
0x01
,
0xbd
,
0x58
,
0xf3
,
0x01
,
0xbd
,
0x58
,
0xfb
,
0x01
,
0xbd
,
0x58
,
0xf9
,
0x80
,
0x9e
,
0x64
,
0x3e
,
0xa0
,
0xf3
,
0xc7
,
0x2f
,
0xba
,
0xc7
,
0xbf
,
0x0d
,
0x15
,
0x29
,
0xbe
,
0x9e
,
0x63
,
0x6f
,
0x35
,
0xd5
,
0x97
,
0xda
,
0xd7
,
0x37
,
0x1a
,
0xfa
,
0x21
,
0x54
,
0x4f
,
0xe5
,
0x89
,
0xe0
,
0x53
,
0x35
,
0xb9
,
0xd2
,
0x54
,
0x3f
,
0x31
,
0xf0
,
0x04
,
0x15
,
0xb6
,
0x04
,
0x2e
,
0xca
,
0xf8
,
0xb7
,
0xc4
,
0xc1
,
0x9f
,
0x01
,
0x00
,
0x00
,
0xff
,
0xff
,
0x85
,
0xaa
,
0x95
,
0x93
,
0xc3
,
0x10
,
0x00
,
0x00
,
// 1339 bytes of a gzipped FileDescriptorProto
0x1f
,
0x8b
,
0x08
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x02
,
0xff
,
0xbc
,
0x57
,
0xdd
,
0x6e
,
0x1b
,
0x45
,
0x14
,
0xd6
,
0xc6
,
0x3f
,
0x89
,
0x8f
,
0xf3
,
0xa7
,
0x29
,
0x2d
,
0xa6
,
0x04
,
0xc9
,
0x1a
,
0xf1
,
0x63
,
0xda
,
0x2a
,
0x54
,
0x69
,
0x25
,
0x2e
,
0x4a
,
0x51
,
0x93
,
0xb4
,
0x6a
,
0x02
,
0x09
,
0xb5
,
0xc6
,
0x56
,
0xb9
,
0x9e
,
0xd8
,
0x83
,
0xbd
,
0x60
,
0xef
,
0x9a
,
0x9d
,
0xb1
,
0x1b
,
0x23
,
0x71
,
0xc3
,
0x1b
,
0x20
,
0xf1
,
0x04
,
0xdc
,
0x73
,
0xc5
,
0x05
,
0x8f
,
0xc0
,
0x13
,
0x70
,
0x09
,
0xcf
,
0x82
,
0xce
,
0x99
,
0xd9
,
0xf5
,
0xec
,
0xda
,
0x4d
,
0x29
,
0x42
,
0xdc
,
0xed
,
0xf9
,
0xce
,
0x37
,
0x73
,
0xf6
,
0xfc
,
0xce
,
0x0c
,
0xec
,
0x1a
,
0x15
,
0xf5
,
0x55
,
0x32
,
0x0e
,
0x23
,
0xb3
,
0x3f
,
0x49
,
0x62
,
0x13
,
0xb3
,
0x8a
,
0x99
,
0x4f
,
0x94
,
0xbe
,
0xb9
,
0x7b
,
0x31
,
0x8a
,
0x7b
,
0xdf
,
0xf4
,
0x86
,
0x32
,
0x8c
,
0xac
,
0x82
,
0xbf
,
0x03
,
0xeb
,
0x47
,
0x88
,
0x9d
,
0x3e
,
0x66
,
0x0c
,
0xca
,
0x27
,
0x52
,
0x0f
,
0x1b
,
0x41
,
0x33
,
0x68
,
0x6d
,
0x0a
,
0xfa
,
0xe6
,
0x9f
,
0x02
,
0xeb
,
0x66
,
0x7b
,
0x1d
,
0x85
,
0xe6
,
0x30
,
0x49
,
0xe4
,
0x1c
,
0x99
,
0x47
,
0xa1
,
0xd1
,
0xc4
,
0xac
,
0x08
,
0xfa
,
0x66
,
0x6f
,
0x40
,
0xe5
,
0xc9
,
0x48
,
0x8d
,
0x75
,
0x63
,
0xad
,
0x59
,
0x6a
,
0x95
,
0x85
,
0x15
,
0xf8
,
0x0f
,
0x6b
,
0x50
,
0x7e
,
0x1e
,
0x1b
,
0xc5
,
0x6e
,
0xc1
,
0xee
,
0x73
,
0x39
,
0x0a
,
0xfb
,
0xd2
,
0xc4
,
0xc9
,
0x61
,
0xbf
,
0x9f
,
0x28
,
0xad
,
0x9d
,
0xa1
,
0x25
,
0x9c
,
0xbd
,
0x0f
,
0xdb
,
0x19
,
0x76
,
0x1a
,
0xf5
,
0xd5
,
0x65
,
0x63
,
0x8d
,
0x0c
,
0x15
,
0x50
,
0x76
,
0x03
,
0xaa
,
0x27
,
0x2a
,
0x1c
,
0x0c
,
0x4d
,
0xa3
,
0xd4
,
0x0c
,
0x5a
,
0x25
,
0xe1
,
0x24
,
0xfc
,
0x15
,
0x11
,
0x4f
,
0xa3
,
0x7e
,
0xa3
,
0x4c
,
0xcb
,
0xac
,
0xc0
,
0xf6
,
0xa0
,
0xd6
,
0x0d
,
0xc7
,
0x4a
,
0x1b
,
0x39
,
0x9e
,
0x34
,
0x2a
,
0xb4
,
0x60
,
0x01
,
0xa0
,
0x4b
,
0xdd
,
0xf9
,
0x44
,
0x35
,
0xaa
,
0xcd
,
0xa0
,
0xb5
,
0x25
,
0xe8
,
0x9b
,
0xb5
,
0xb2
,
0xd8
,
0x34
,
0xd6
,
0x9b
,
0x41
,
0xab
,
0x7e
,
0xb0
,
0xbd
,
0x4f
,
0x61
,
0xdc
,
0x77
,
0xa8
,
0xc8
,
0x42
,
0xb7
,
0x07
,
0xb5
,
0x4e
,
0x38
,
0x88
,
0xa4
,
0x99
,
0x26
,
0xaa
,
0xb1
,
0x41
,
0x6e
,
0x2d
,
0x00
,
0x1e
,
0xc2
,
0xee
,
0x22
,
0x88
,
0xc7
,
0xf1
,
0x78
,
0x1c
,
0x1a
,
0x7f
,
0xef
,
0xe0
,
0xea
,
0xbd
,
0x6f
,
0x03
,
0xb4
,
0x13
,
0xd5
,
0xa3
,
0x65
,
0x36
,
0xba
,
0xf5
,
0x83
,
0xba
,
0x23
,
0x63
,
0x68
,
0x85
,
0xa7
,
0xe6
,
0x3f
,
0x05
,
0x70
,
0xcd
,
0x4b
,
0x18
,
0x6d
,
0x11
,
0x7d
,
0x15
,
0x33
,
0x0e
,
0x95
,
0x8e
,
0x91
,
0x46
,
0x51
,
0x24
,
0xeb
,
0x07
,
0x9b
,
0x6e
,
0x3d
,
0x61
,
0xc2
,
0xaa
,
0xd8
,
0x6d
,
0xd8
,
0x68
,
0x27
,
0xf1
,
0x24
,
0xd6
,
0x72
,
0x44
,
0x01
,
0xad
,
0x1f
,
0xec
,
0x38
,
0x5a
,
0x0a
,
0x8b
,
0x8c
,
0xc0
,
0xee
,
0x40
,
0x85
,
0x6a
,
0x89
,
0x62
,
0x5c
,
0x3f
,
0xb8
,
0xe1
,
0x98
,
0x05
,
0xdb
,
0xc2
,
0x92
,
0xf8
,
0x97
,
0x50
,
0x23
,
0xb9
,
0x13
,
0x7e
,
0xa7
,
0xd8
,
0x4d
,
0xd8
,
0x38
,
0x97
,
0x97
,
0x47
,
0x73
,
0xa3
,
0xd2
,
0x0a
,
0xca
,
0x64
,
0x4c
,
0xe9
,
0xb9
,
0xbc
,
0xec
,
0x5e
,
0x6a
,
0x97
,
0x72
,
0x27
,
0x39
,
0xfc
,
0xa9
,
0xd4
,
0x69
,
0xaa
,
0xad
,
0xc4
,
0x3f
,
0x81
,
0x6a
,
0xf7
,
0xf2
,
0x1f
,
0xee
,
0x8a
,
0xab
,
0xd7
,
0x72
,
0xab
,
0x1f
,
0x42
,
0x9d
,
0x7e
,
0xeb
,
0x69
,
0xac
,
0x75
,
0x38
,
0x61
,
0xfb
,
0xc0
,
0x48
,
0x6c
,
0xcb
,
0xc4
,
0xe0
,
0x9e
,
0xfe
,
0x66
,
0x2b
,
0x34
,
0xbc
,
0x05
,
0xdb
,
0x4f
,
0x66
,
0x61
,
0x5f
,
0x45
,
0x3d
,
0xd5
,
0x96
,
0x89
,
0x1c
,
0xa7
,
0x86
,
0x0e
,
0x07
,
0x8a
,
0x56
,
0x59
,
0x43
,
0x87
,
0x03
,
0xc5
,
0xff
,
0x0c
,
0x60
,
0xe7
,
0x38
,
0x8e
,
0xb4
,
0x8a
,
0xf4
,
0x54
,
0x3b
,
0xee
,
0xbe
,
0x17
,
0x13
,
0x57
,
0x03
,
0xbb
,
0x7e
,
0x0d
,
0x20
,
0x2e
,
0xbc
,
0xb0
,
0xbd
,
0x97
,
0xba
,
0xea
,
0x72
,
0xb8
,
0x95
,
0x86
,
0x9c
,
0x40
,
0x91
,
0xc6
,
0xe1
,
0x7e
,
0xce
,
0x27
,
0x97
,
0x48
,
0xe6
,
0x6f
,
0x6c
,
0x35
,
0x22
,
0xe7
,
0xfa
,
0xc3
,
0xa2
,
0x2b
,
0x2e
,
0xaf
,
0xd7
,
0xdd
,
0xc2
,
0xbc
,
0x52
,
0x14
,
0xc8
,
0x7c
,
0x0a
,
0xb5
,
0xac
,
0x37
,
0x59
,
0x03
,
0xd6
,
0xf3
,
0x1d
,
0x9e
,
0x8a
,
0x18
,
0x9e
,
0xf6
,
0xf4
,
0xe2
,
0x73
,
0x35
,
0x27
,
0x17
,
0x36
,
0x85
,
0x93
,
0x58
,
0x13
,
0xea
,
0xcf
,
0x63
,
0x13
,
0x46
,
0x83
,
0x76
,
0xfc
,
0x42
,
0x25
,
0x2e
,
0xc5
,
0x3e
,
0x84
,
0x2d
,
0x7d
,
0xd8
,
0xeb
,
0x4d
,
0xc7
,
0xf4
,
0x5b
,
0x25
,
0x61
,
0x05
,
0x1e
,
0xc1
,
0x66
,
0x66
,
0xb6
,
0xa3
,
0x0c
,
0xbb
,
0x0b
,
0x90
,
0xc9
,
0x68
,
0xbc
,
0xe4
,
0xc5
,
0x34
,
0x53
,
0x08
,
0x8f
,
0xc3
,
0xee
,
0xa4
,
0x35
,
0xaf
,
0x12
,
0x17
,
0xd6
,
0x65
,
0x7e
,
0xc6
,
0xe0
,
0x7f
,
0x94
,
0x5d
,
0x1b
,
0xa1
,
0x8f
,
0xc7
,
0x38
,
0x45
,
0x5d
,
0xfb
,
0xd6
,
0x44
,
0x2a
,
0xb2
,
0x16
,
0xec
,
0x9c
,
0x49
,
0x6d
,
0xcb
,
0xdf
,
0x4d
,
0x27
,
0x5b
,
0x74
,
0x45
,
0x18
,
0x47
,
0x62
,
0x06
,
0x75
,
0x63
,
0x23
,
0x47
,
0xdd
,
0x4b
,
0xe7
,
0xfa
,
0x12
,
0xce
,
0xee
,
0x42
,
0x3d
,
0xc3
,
0x4e
,
0x1f
,
0xbb
,
0xe4
,
0x14
,
0x47
,
0x86
,
0x4f
,
0x61
,
0xef
,
0xc2
,
0xd6
,
0x62
,
0x97
,
0x70
,
0xac
,
0xdc
,
0xc8
,
0xcb
,
0x83
,
0xec
,
0x5e
,
0x2e
,
0x62
,
0x55
,
0xda
,
0xf6
,
0x5a
,
0x31
,
0x02
,
0x1d
,
0x65
,
0x72
,
0x41
,
0x7b
,
0x00
,
0xdb
,
0xb8
,
0x8b
,
0xb7
,
0x70
,
0xfd
,
0xe5
,
0x0b
,
0x0b
,
0x54
,
0xf6
,
0x08
,
0xde
,
0x46
,
0xc4
,
0xc6
,
0x60
,
0x81
,
0x1f
,
0x0f
,
0x65
,
0x34
,
0x50
,
0x7d
,
0x1a
,
0x9e
,
0x25
,
0x71
,
0x15
,
0x85
,
0x3d
,
0x5a
,
0xea
,
0xa5
,
0x46
,
0x2d
,
0x37
,
0x84
,
0x0a
,
0x5a
,
0xb1
,
0xd4
,
0x7a
,
0x9f
,
0x41
,
0x73
,
0x61
,
0xa0
,
0xa0
,
0x4c
,
0x7f
,
0x04
,
0xe8
,
0x47
,
0x5e
,
0xc9
,
0x4b
,
0xf3
,
0x2d
,
0x94
,
0x9e
,
0x8e
,
0x8c
,
0xa6
,
0x03
,
0xb4
,
0x4e
,
0xc5
,
0x5d
,
0x84
,
0xa9
,
0x2f
,
0x26
,
0x13
,
0x62
,
0x6c
,
0xba
,
0xbe
,
0xb0
,
0x22
,
0xff
,
0xad
,
0x04
,
0xd7
,
0x0b
,
0x93
,
0xf3
,
0x44
,
0xc9
,
0xbe
,
0xa2
,
0x5e
,
0xea
,
0xe5
,
0xeb
,
0xcc
,
0x89
,
0xd8
,
0x4b
,
0x43
,
0xbf
,
0xbc
,
0x9c
,
0x84
,
0x9d
,
0x92
,
0xd0
,
0xe1
,
0x67
,
0x4b
,
0xc9
,
0x0a
,
0x78
,
0xbc
,
0x19
,
0x2c
,
0x02
,
0xdb
,
0x3e
,
0xf4
,
0x8d
,
0x3b
,
0x44
,
0xd3
,
0x31
,
0xce
,
0x5a
,
0x5b
,
0x1a
,
0x4e
,
0xc2
,
0x5a
,
0x1b
,
0x79
,
0xb5
,
0x56
,
0x5d
,
0x5d
,
0x6b
,
0x1e
,
0x05
,
0x67
,
0xaf
,
0xb1
,
0x85
,
0x6a
,
0x4b
,
0xa1
,
0x24
,
0x32
,
0x19
,
0x0f
,
0x73
,
0xa4
,
0xda
,
0x63
,
0x8f
,
0x9c
,
0xb7
,
0xe7
,
0x63
,
0x01
,
0x45
,
0xde
,
0x2c
,
0x4b
,
0x35
,
0xf1
,
0x6a
,
0x96
,
0x97
,
0x47
,
0xb1
,
0xae
,
0x7b
,
0x69
,
0x26
,
0x88
,
0x06
,
0x44
,
0xcb
,
0x83
,
0x18
,
0x37
,
0xe9
,
0x62
,
0x6d
,
0xb3
,
0x91
,
0x8a
,
0x98
,
0xaf
,
0x51
,
0x21
,
0x5f
,
0x36
,
0x1b
,
0x45
,
0x98
,
0x71
,
0xd8
,
0x9c
,
0xb8
,
0xce
,
0xc7
,
0x01
,
0xd6
,
0xd8
,
0x22
,
0x5a
,
0x0e
,
0xe3
,
0x3f
,
0x07
,
0xb0
,
0x53
,
0xc8
,
0x1c
,
0xbb
,
0x8f
,
0x99
,
0xc1
,
0xec
,
0xb9
,
0xa9
,
0xbe
,
0xb7
,
0xfa
,
0x6c
,
0xb4
,
0x19
,
0x16
,
0x8e
,
0xcb
,
0x9a
,
0x50
,
0xee
,
0x4b
,
0x23
,
0x0b
,
0x07
,
0xb4
,
0x3d
,
0x45
,
0x49
,
0xc3
,
0x3e
,
0x06
,
0x58
,
0xc4
,
0xcc
,
0x8d
,
0x80
,
0x37
,
0x97
,
0xf6
,
0xb6
,
0x6a
,
0xe1
,
0x51
,
0xf9
,
0x5f
,
0xc1
,
0xe2
,
0x64
,
0xf7
,
0xea
,
0x26
,
0x58
,
0x5d
,
0x37
,
0xf6
,
0xe0
,
0x75
,
0x75
,
0xb3
,
0x07
,
0x35
,
0x93
,
0x5d
,
0x9a
,
0x6c
,
0x45
,
0x2d
,
0x00
,
0xcc
,
0x7b
,
0xfb
,
0xd9
,
0x99
,
0x7f
,
0xd7
,
0xca
,
0x64
,
0xb6
,
0x0f
,
0xd0
,
0x7e
,
0x76
,
0x96
,
0x16
,
0x51
,
0x65
,
0x65
,
0x11
,
0x79
,
0x0c
,
0xb4
,
0xa4
,
0xb3
,
0x2b
,
0x54
,
0xd5
,
0x5e
,
0xa1
,
0x32
,
0x00
,
0xb5
,
0x74
,
0x93
,
0x18
,
0x62
,
0xbe
,
0xd6
,
0xad
,
0x36
,
0x03
,
0xf8
,
0xaf
,
0x01
,
0xec
,
0x7c
,
0xa1
,
0x5e
,
0x90
,
0xe1
,
0x8e
,
0x51
,
0x93
,
0x73
,
0x3d
,
0x78
,
0x4d
,
0x3f
,
0x19
,
0x94
,
0xb5
,
0x51
,
0xd6
,
0xc5
,
0x8a
,
0xa0
,
0x6f
,
0x76
,
0x1f
,
0xae
,
0x6b
,
0xd5
,
0x8b
,
0xa3
,
0xbe
,
0xee
,
0x84
,
0x51
,
0x4f
,
0x75
,
0x8c
,
0x4c
,
0x4c
,
0x37
,
0x6d
,
0xa2
,
0x8a
,
0x58
,
0xad
,
0x4c
,
0xeb
,
0xcb
,
0xa5
,
0x81
,
0x2c
,
0x55
,
0x88
,
0x5f
,
0x84
,
0xf9
,
0x0b
,
0xd8
,
0xa2
,
0xe1
,
0x46
,
0x11
,
0x78
,
0xfd
,
0x5f
,
0xce
,
0x85
,
0xa4
,
0x54
,
0x08
,
0x09
,
0xa6
,
0x26
,
0xd4
,
0x5e
,
0xa9
,
0x6c
,
0x88
,
0x4c
,
0xe6
,
0x1f
,
0xc0
,
0x96
,
0xfd
,
0x7a
,
0x45
,
0xac
,
0xf8
,
0x8f
,
0x01
,
0x6c
,
0xa7
,
0x85
,
0xd3
,
0x7e
,
0x76
,
0x76
,
0xd5
,
0x3f
,
0xde
,
0x82
,
0xdd
,
0xc9
,
0x82
,
0x29
,
0xbc
,
0xdf
,
0x5d
,
0xc2
,
0xd9
,
0x03
,
0xa8
,
0x7b
,
0x98
,
0xbb
,
0xa2
,
0xbc
,
0xb5
,
0xdc
,
0x25
,
0xee
,
0xb9
,
0x21
,
0x7c
,
0x36
,
0xef
,
0x03
,
0x9c
,
0x48
,
0x8d
,
0x17
,
0xdf
,
0x7f
,
0x95
,
0x65
,
0x34
,
0x92
,
0x66
,
0x19
,
0xbf
,
0x91
,
0x19
,
0xd2
,
0x1b
,
0xc3
,
0x3d
,
0x16
,
0x48
,
0xe0
,
0xdf
,
0xc3
,
0x0e
,
0x9a
,
0xe8
,
0x28
,
0x73
,
0x2e
,
0xbf
,
0x3e
,
0xb8
,
0xf7
,
0xdf
,
0x98
,
0x6a
,
0xc1
,
0xfa
,
0xc5
,
0x95
,
0x07
,
0x78
,
0xaa
,
0xe6
,
0xbf
,
0x04
,
0xb0
,
0xed
,
0xec
,
0xe3
,
0xe3
,
0xea
,
0x7f
,
0x36
,
0xcf
,
0x3e
,
0x82
,
0xca
,
0x2c
,
0xc6
,
0xbb
,
0x6f
,
0xe5
,
0x55
,
0xa9
,
0xb1
,
0x3c
,
0xfe
,
0x7b
,
0x00
,
0xb5
,
0x13
,
0x25
,
0x13
,
0x73
,
0xa1
,
0x24
,
0xd5
,
0xc2
,
0xec
,
0x25
,
0x6f
,
0xbd
,
0xd9
,
0x8a
,
0xb7
,
0xde
,
0x6c
,
0xe5
,
0x5b
,
0x6f
,
0xb6
,
0xf4
,
0xd6
,
0x1b
,
0xe6
,
0xde
,
0x7a
,
0x45
,
0xf7
,
0xcb
,
0xbe
,
0xfb
,
0x37
,
0x61
,
0x43
,
0xab
,
0x6f
,
0xa7
,
0x78
,
0x43
,
0x75
,
0xdd
,
0x97
,
0xc9
,
0x57
,
0x0f
,
0x1a
,
0xfe
,
0x21
,
0xd4
,
0x4e
,
0xf5
,
0x89
,
0x92
,
0x23
,
0x33
,
0x9c
,
0x23
,
0x35
,
0x4c
,
0x05
,
0xf2
,
0x60
,
0x43
,
0x2c
,
0x80
,
0x8b
,
0x2a
,
0xbd
,
0xa0
,
0xef
,
0xfd
,
0x1d
,
0x00
,
0x00
,
0xff
,
0xff
,
0xe7
,
0xeb
,
0xd6
,
0x7a
,
0x6e
,
0x0f
,
0x00
,
0x00
,
}
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