Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
C
contrib
Manage
Activity
Members
Labels
Plan
Issues
0
Issue boards
Milestones
Wiki
Code
Merge requests
2
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package Registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
blockchain
contrib
Commits
fd6f11a0
Commit
fd6f11a0
authored
6 years ago
by
Miguel Montes
Browse files
Options
Downloads
Patches
Plain Diff
Cambio de organización del código de bfa_client
parent
37d9680f
No related branches found
No related tags found
No related merge requests found
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
bfa_client/src/bfa/node.go
+447
-0
447 additions, 0 deletions
bfa_client/src/bfa/node.go
bfa_client/src/client/bfa_client.go
+13
-489
13 additions, 489 deletions
bfa_client/src/client/bfa_client.go
bfa_client/src/util/util.go
+42
-0
42 additions, 0 deletions
bfa_client/src/util/util.go
with
502 additions
and
489 deletions
bfa_client/src/bfa/node.go
0 → 100644
+
447
−
0
View file @
fd6f11a0
package
bfa
import
(
.
"../util"
"fmt"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/consensus/clique"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/crypto/sha3"
"github.com/ethereum/go-ethereum/rlp"
"github.com/ethereum/go-ethereum/rpc"
"sort"
"strconv"
)
type
Node
rpc
.
Client
type
Snapshot
struct
{
Number
uint64
`json:"number"`
// Block number where the snapshot was created
Hash
common
.
Hash
`json:"hash"`
// Block hash where the snapshot was created
Signers
map
[
common
.
Address
]
struct
{}
`json:"signers"`
// Set of authorized signers at this moment
Recents
map
[
uint64
]
common
.
Address
`json:"recents"`
// Set of recent signers for spam protections
Votes
[]
*
clique
.
Vote
`json:"votes"`
// List of votes cast in chronological order
Tally
map
[
common
.
Address
]
clique
.
Tally
`json:"tally"`
// Current vote tally to avoid recalculating
}
type
Tally
struct
{
True
int
`json:"true"`
False
int
`json:"false"`
Null
int
`json:"null"`
}
type
Proposals
struct
{
BlockNumber
int64
`json:"number"`
// Block number where the snapshot was created
Proposals
[]
string
`json:"proposals"`
// List of proposals being voted
Signers
[]
string
`json:"signers"`
// List of authorized signers at this moment
Tally
map
[
string
]
*
Tally
`json:"tally"`
// Count of positive, negative and empty votes for a proposal
Votes
map
[
string
]
map
[
string
]
*
bool
`json:"votes"`
// List of votes for each proposal
}
type
SealerInfo
struct
{
Address
string
CurrentBlock
int64
Since
int64
FirstBlock
int64
LastBlock
int64
}
func
sigHash
(
header
*
types
.
Header
)
(
hash
common
.
Hash
)
{
hasher
:=
sha3
.
NewKeccak256
()
rlp
.
Encode
(
hasher
,
[]
interface
{}{
header
.
ParentHash
,
header
.
UncleHash
,
header
.
Coinbase
,
header
.
Root
,
header
.
TxHash
,
header
.
ReceiptHash
,
header
.
Bloom
,
header
.
Difficulty
,
header
.
Number
,
header
.
GasLimit
,
header
.
GasUsed
,
header
.
Time
,
header
.
Extra
[
:
len
(
header
.
Extra
)
-
65
],
// Yes, this will panic if extra is too short
header
.
MixDigest
,
header
.
Nonce
,
})
hasher
.
Sum
(
hash
[
:
0
])
return
hash
}
func
(
node
*
Node
)
Call
(
result
interface
{},
method
string
,
args
...
interface
{})
{
Check
((
*
rpc
.
Client
)(
node
)
.
Call
(
result
,
method
,
args
...
))
}
func
(
node
*
Node
)
blockNumber
()
int64
{
var
bn
rpc
.
BlockNumber
node
.
Call
(
&
bn
,
"eth_blockNumber"
)
return
bn
.
Int64
()
}
func
(
node
*
Node
)
GetBlockByNumber
(
blockNumber
int64
)
types
.
Header
{
var
(
number
string
resp
types
.
Header
)
if
blockNumber
<
0
{
number
=
"latest"
}
else
{
number
=
fmt
.
Sprintf
(
"0x%x"
,
blockNumber
)
}
node
.
Call
(
&
resp
,
"eth_getBlockByNumber"
,
number
,
false
)
return
resp
}
func
getSigner
(
header
*
types
.
Header
)
(
signer
string
,
err
error
)
{
signature
:=
header
.
Extra
[
len
(
header
.
Extra
)
-
65
:
]
hash
:=
sigHash
(
header
)
.
Bytes
()
pubkey
,
err
:=
crypto
.
Ecrecover
(
hash
,
signature
)
address
:=
make
([]
byte
,
20
)
copy
(
address
,
crypto
.
Keccak256
(
pubkey
[
1
:
])[
12
:
])
signer
=
ToHex
(
address
)
return
}
func
(
node
*
Node
)
GetBlockSigner
(
blockNumber
int64
)
(
signer
string
)
{
header
:=
node
.
GetBlockByNumber
(
blockNumber
)
signer
,
err
:=
getSigner
(
&
header
)
Check
(
err
)
return
}
func
(
node
*
Node
)
GetSnapshot
()
(
snapshot
Snapshot
)
{
node
.
Call
(
&
snapshot
,
"clique_getSnapshot"
,
nil
)
return
}
func
(
node
*
Node
)
GetSnapshotAtHash
(
hash
common
.
Hash
)
(
snapshot
Snapshot
)
{
node
.
Call
(
&
snapshot
,
"clique_getSnapshotAtHash"
,
hash
)
return
}
func
(
node
*
Node
)
GetSnapshotAtBlock
(
blockNumber
int64
)
(
snapshot
Snapshot
)
{
node
.
Call
(
&
snapshot
,
"clique_getSnapshot"
,
fmt
.
Sprintf
(
"0x%x"
,
blockNumber
))
return
}
func
(
node
*
Node
)
GetSigners
()
(
signers
[]
string
)
{
var
s
[]
common
.
Address
node
.
Call
(
&
s
,
"clique_getSigners"
,
nil
)
for
_
,
signer
:=
range
s
{
signers
=
append
(
signers
,
ToHex
(
signer
.
Bytes
()))
}
return
}
func
(
node
*
Node
)
GetSignersAtHash
(
hash
common
.
Hash
)
(
signers
[]
string
)
{
var
s
[]
common
.
Address
node
.
Call
(
&
signers
,
"clique_getSignersAtHash"
,
hash
)
for
_
,
signer
:=
range
s
{
signers
=
append
(
signers
,
ToHex
(
signer
.
Bytes
()))
}
return
}
func
(
node
*
Node
)
GetSignersAtBlock
(
blockNumber
int64
)
(
signers
[]
string
)
{
var
s
[]
common
.
Address
node
.
Call
(
&
s
,
"clique_getSigners"
,
"0x"
+
strconv
.
FormatInt
(
blockNumber
,
16
))
for
_
,
signer
:=
range
s
{
signers
=
append
(
signers
,
ToHex
(
signer
.
Bytes
()))
}
return
}
func
(
node
*
Node
)
GetVotes
(
blockNumber
int64
)
(
votes
Proposals
)
{
var
(
snapshot
Snapshot
)
if
blockNumber
<
0
{
snapshot
=
node
.
GetSnapshot
()
}
else
{
snapshot
=
node
.
GetSnapshotAtBlock
(
blockNumber
)
}
votes
.
BlockNumber
=
int64
(
snapshot
.
Number
)
for
signer
:=
range
snapshot
.
Signers
{
votes
.
Signers
=
append
(
votes
.
Signers
,
ToHex
(
signer
[
:
]))
sort
.
Strings
(
votes
.
Signers
)
}
for
proposal
:=
range
snapshot
.
Tally
{
votes
.
Proposals
=
append
(
votes
.
Proposals
,
ToHex
(
proposal
[
:
]))
}
votes
.
Votes
=
make
(
map
[
string
]
map
[
string
]
*
bool
)
votes
.
Tally
=
make
(
map
[
string
]
*
Tally
)
for
_
,
v
:=
range
snapshot
.
Votes
{
proposal
:=
ToHex
(
v
.
Address
[
:
])
signer
:=
ToHex
(
v
.
Signer
[
:
])
if
votes
.
Votes
[
proposal
]
==
nil
{
votes
.
Votes
[
proposal
]
=
make
(
map
[
string
]
*
bool
)
for
_
,
signer
:=
range
votes
.
Signers
{
votes
.
Votes
[
proposal
][
signer
]
=
nil
}
votes
.
Tally
[
proposal
]
=
&
Tally
{
0
,
0
,
len
(
votes
.
Signers
)}
}
votes
.
Votes
[
proposal
][
signer
]
=
&
v
.
Authorize
if
v
.
Authorize
{
votes
.
Tally
[
proposal
]
.
True
+=
1
}
else
{
votes
.
Tally
[
proposal
]
.
False
+=
1
}
votes
.
Tally
[
proposal
]
.
Null
-=
1
}
return
}
func
(
node
*
Node
)
SealersStatus
()
map
[
string
]
int64
{
status
:=
make
(
map
[
string
]
int64
)
for
_
,
address
:=
range
node
.
GetSigners
()
{
status
[
address
]
=
-
1
}
notSeen
:=
int64
(
len
(
status
))
block
:=
node
.
GetBlockByNumber
(
-
1
)
blockNumber
:=
block
.
Number
.
Int64
()
until
:=
blockNumber
-
5
*
notSeen
for
notSeen
>
0
{
signer
,
_
:=
getSigner
(
&
block
)
if
status
[
signer
]
==
-
1
{
status
[
signer
]
=
block
.
Number
.
Int64
()
notSeen
--
}
if
blockNumber
==
until
{
break
}
blockNumber
--
block
=
node
.
GetBlockByNumber
(
blockNumber
)
}
return
status
}
func
(
node
*
Node
)
GetSealerInception
(
address
string
)
(
since
int64
)
{
if
signers
:=
node
.
GetSigners
();
!
Contains
(
signers
,
address
)
{
return
-
1
}
lo
:=
int64
(
0
)
hi
:=
node
.
blockNumber
()
for
lo
<
hi
{
mid
:=
lo
+
(
hi
-
lo
)
/
2
signers
:=
node
.
GetSignersAtBlock
(
mid
)
if
Contains
(
signers
,
address
)
{
hi
=
mid
}
else
{
lo
=
mid
+
1
}
}
return
hi
}
func
(
node
*
Node
)
getSignerFirstBlock
(
signer
string
,
since
int64
,
until
int64
)
(
blockNumber
int64
)
{
if
since
<
0
{
return
-
1
}
//snapshot := node.GetSnapshotAtBlock(since)
var
(
count
int64
=
20
found
int64
=
-
1
)
// first, we look close to the inception
if
blockNumber
,
_
=
node
.
searchSnapshotForward
(
since
,
signer
,
count
);
blockNumber
>
0
{
return
}
// next, we do a coarse search
since
+=
count
for
i
:=
since
+
10000
;
i
<
until
&&
found
==
-
1
;
i
+=
10000
{
if
found
,
_
=
node
.
searchSnapshotBackward
(
i
,
signer
,
0
);
found
==
-
1
{
// still not found
since
=
i
}
}
if
found
>
0
{
until
=
found
}
n
:=
Min
(
10
,
(
until
-
since
)
/
count
+
1
)
// number of goroutines
ch
:=
make
(
chan
int64
)
for
i
:=
int64
(
0
);
i
<
n
;
i
++
{
go
func
()
{
for
blockNumber
:=
<-
ch
;
blockNumber
>
0
;
blockNumber
=
<-
ch
{
cnt
:=
Min
(
count
,
until
-
blockNumber
+
1
)
if
found
,
_
:=
node
.
searchSnapshotForward
(
blockNumber
,
signer
,
cnt
);
found
>
0
{
ch
<-
found
}
}
ch
<-
(
-
1
)
}()
}
for
{
select
{
case
ch
<-
since
:
switch
{
case
since
<
0
:
continue
case
since
+
count
<
until
:
since
+=
count
default
:
since
=
-
1
//we have exhausted the search space
}
case
found
:=
<-
ch
:
switch
{
case
found
<
0
:
n
--
// a goroutine has ended
if
n
==
0
{
// all goroutines have ended
return
}
case
blockNumber
<
0
:
blockNumber
=
found
// first time we see this signer
since
=
-
1
// Notify everyone
case
found
<
blockNumber
:
blockNumber
=
found
// found an earlier block
}
}
}
}
func
(
node
*
Node
)
getSignerLastBlock
(
signer
string
,
since
int64
,
until
int64
)
(
blockNumber
int64
)
{
if
since
<
0
{
return
-
1
}
var
(
count
int64
=
20
visited
int64
=
0
found
int64
=
-
1
)
// first, we look close to the last block
if
blockNumber
,
visited
=
node
.
searchSnapshotBackward
(
until
,
signer
,
0
);
blockNumber
>
0
{
return
}
// next, we do a coarse search
until
-=
visited
for
i
:=
until
-
10000
;
i
>
since
&&
found
==
-
1
;
i
-=
10000
{
if
found
,
_
=
node
.
searchSnapshotBackward
(
i
,
signer
,
0
);
found
==
-
1
{
// still not found
until
=
i
}
}
if
found
>
0
{
since
=
found
}
n
:=
Min
(
10
,
(
until
-
since
)
/
count
+
1
)
// number of goroutines
ch
:=
make
(
chan
int64
)
for
i
:=
int64
(
0
);
i
<
n
;
i
++
{
go
func
()
{
for
blockNumber
:=
<-
ch
;
blockNumber
>
0
;
blockNumber
=
<-
ch
{
cnt
:=
Min
(
count
,
blockNumber
-
since
+
1
)
if
found
,
_
:=
node
.
searchSnapshotBackward
(
blockNumber
,
signer
,
cnt
);
found
>
0
{
ch
<-
found
}
}
ch
<-
(
-
1
)
}()
}
for
{
select
{
case
ch
<-
until
:
switch
{
case
until
<
0
:
continue
case
until
-
count
>
since
:
until
-=
count
default
:
until
=
-
1
//we have exhausted the search space
}
case
found
:=
<-
ch
:
switch
{
case
found
<
0
:
n
--
// a goroutine has ended
if
n
==
0
{
// all goroutines have ended
return
}
case
blockNumber
<
0
:
blockNumber
=
found
// first time we see this signer
until
=
-
1
// Notify everyone
case
found
>
blockNumber
:
blockNumber
=
found
// found a later block
}
}
}
}
func
(
node
*
Node
)
searchSnapshotForward
(
blockNumber
int64
,
signer
string
,
count
int64
)
(
found
int64
,
visited
int64
)
{
//printDebug("In",fmt.Sprintf("(%v, %v, %v)", blockNumber, signer, count))
//defer printDebug("Out", "")
found
=
-
1
if
blockNumber
+
count
<
1
{
return
}
for
count
>
0
{
snapshot
:=
node
.
GetSnapshotAtBlock
(
blockNumber
+
count
-
1
)
recents
:=
int64
(
len
(
snapshot
.
Recents
))
visited
+=
recents
count
-=
recents
for
b
,
s
:=
range
snapshot
.
Recents
{
if
ToHex
(
s
[
:
])
==
signer
{
found
=
int64
(
b
)
}
}
}
return
}
func
(
node
*
Node
)
searchSnapshotBackward
(
blockNumber
int64
,
signer
string
,
count
int64
)
(
found
int64
,
visited
int64
)
{
//printDebug("In",fmt.Sprintf("(%v, %v, %v)", blockNumber, signer, count))
//defer printDebug("Out", "")
found
=
-
1
if
blockNumber
<
1
{
// Genesis block has no signers
return
}
count
=
Min
(
count
,
blockNumber
)
// Never search below block 1
for
{
snapshot
:=
node
.
GetSnapshotAtBlock
(
blockNumber
-
visited
)
visited
+=
int64
(
len
(
snapshot
.
Recents
))
if
count
==
0
{
count
=
Min
(
blockNumber
,
int64
(
2
*
len
(
snapshot
.
Signers
)))
}
for
b
,
s
:=
range
snapshot
.
Recents
{
if
ToHex
(
s
[
:
])
==
signer
{
found
=
int64
(
b
)
return
}
}
if
visited
>=
count
{
return
}
}
}
func
(
node
*
Node
)
SealerInfo
(
sealer
string
)
(
info
SealerInfo
,
err
error
)
{
info
.
Address
=
sealer
info
.
CurrentBlock
=
node
.
blockNumber
()
info
.
Since
=
node
.
GetSealerInception
(
sealer
)
if
info
.
Since
==
-
1
{
return
info
,
fmt
.
Errorf
(
"%q is not a sealer"
,
sealer
)
}
info
.
FirstBlock
=
node
.
getSignerFirstBlock
(
sealer
,
info
.
Since
+
1
,
info
.
CurrentBlock
)
info
.
LastBlock
=
node
.
getSignerLastBlock
(
sealer
,
info
.
FirstBlock
,
info
.
CurrentBlock
)
return
}
func
Dial
(
url
string
)
*
Node
{
client
,
err
:=
rpc
.
Dial
(
url
)
Check
(
err
)
return
(
*
Node
)(
client
)
}
func
(
node
*
Node
)
Close
()
{
(
*
rpc
.
Client
)(
node
)
.
Close
()
}
This diff is collapsed.
Click to expand it.
bfa_client/src/client/bfa_client.go
+
13
−
489
View file @
fd6f11a0
...
@@ -4,461 +4,27 @@ import (
...
@@ -4,461 +4,27 @@ import (
"encoding/json"
"encoding/json"
"flag"
"flag"
"fmt"
"fmt"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/consensus/clique"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/crypto/sha3"
"github.com/ethereum/go-ethereum/rlp"
"github.com/ethereum/go-ethereum/rpc"
"log"
"log"
"os"
"os"
"path"
"path"
"runtime"
"sort"
"sort"
"strconv"
"strconv"
"strings"
"strings"
"../util"
"../bfa"
)
)
const
(
const
(
DefaultURL
=
"http://localhost:8545"
DefaultURL
=
"http://localhost:8545"
)
)
type
Node
rpc
.
Client
type
Node
=
bfa
.
Node
func
toHex
(
b
[]
byte
)
string
{
func
printVotes
(
node
*
bfa
.
Node
,
useJson
bool
)
{
return
fmt
.
Sprintf
(
"0x%02x"
,
b
)
votes
:=
node
.
GetVotes
(
-
1
)
}
func
(
node
*
Node
)
blockNumber
()
int64
{
var
bn
rpc
.
BlockNumber
node
.
Call
(
&
bn
,
"eth_blockNumber"
)
return
bn
.
Int64
()
}
func
check
(
err
error
)
{
if
err
!=
nil
{
panic
(
err
.
Error
())
}
}
func
(
node
*
Node
)
Call
(
result
interface
{},
method
string
,
args
...
interface
{})
{
check
((
*
rpc
.
Client
)(
node
)
.
Call
(
result
,
method
,
args
...
))
}
func
(
node
*
Node
)
getBlockByNumber
(
blockNumber
int64
)
types
.
Header
{
var
(
number
string
resp
types
.
Header
)
if
blockNumber
<
0
{
number
=
"latest"
}
else
{
number
=
fmt
.
Sprintf
(
"0x%x"
,
blockNumber
)
}
node
.
Call
(
&
resp
,
"eth_getBlockByNumber"
,
number
,
false
)
return
resp
}
func
getSigner
(
header
*
types
.
Header
)
(
signer
string
,
err
error
)
{
signature
:=
header
.
Extra
[
len
(
header
.
Extra
)
-
65
:
]
hash
:=
sigHash
(
header
)
.
Bytes
()
pubkey
,
err
:=
crypto
.
Ecrecover
(
hash
,
signature
)
address
:=
make
([]
byte
,
20
)
copy
(
address
,
crypto
.
Keccak256
(
pubkey
[
1
:
])[
12
:
])
signer
=
toHex
(
address
)
return
}
func
(
node
*
Node
)
getBlockSigner
(
blockNumber
int64
)
(
signer
string
)
{
header
:=
node
.
getBlockByNumber
(
blockNumber
)
signer
,
err
:=
getSigner
(
&
header
)
check
(
err
)
return
}
type
Snapshot
struct
{
Number
uint64
`json:"number"`
// Block number where the snapshot was created
Hash
common
.
Hash
`json:"hash"`
// Block hash where the snapshot was created
Signers
map
[
common
.
Address
]
struct
{}
`json:"signers"`
// Set of authorized signers at this moment
Recents
map
[
uint64
]
common
.
Address
`json:"recents"`
// Set of recent signers for spam protections
Votes
[]
*
clique
.
Vote
`json:"votes"`
// List of votes cast in chronological order
Tally
map
[
common
.
Address
]
clique
.
Tally
`json:"tally"`
// Current vote tally to avoid recalculating
}
type
Tally
struct
{
True
int
`json:"true"`
False
int
`json:"false"`
Null
int
`json:"null"`
}
type
Proposals
struct
{
BlockNumber
int64
`json:"number"`
// Block number where the snapshot was created
Proposals
[]
string
`json:"proposals"`
// List of proposals being voted
Signers
[]
string
`json:"signers"`
// List of authorized signers at this moment
Tally
map
[
string
]
*
Tally
`json:"tally"`
// Count of positive, negative and empty votes for a proposal
Votes
map
[
string
]
map
[
string
]
*
bool
`json:"votes"`
// List of votes for each proposal
}
func
(
node
*
Node
)
getSnapshot
()
(
snapshot
Snapshot
)
{
node
.
Call
(
&
snapshot
,
"clique_getSnapshot"
,
nil
)
return
}
func
(
node
*
Node
)
getSnapshotAtHash
(
hash
common
.
Hash
)
(
snapshot
Snapshot
)
{
node
.
Call
(
&
snapshot
,
"clique_getSnapshotAtHash"
,
hash
)
return
}
func
(
node
*
Node
)
getSnapshotAtBlock
(
blockNumber
int64
)
Snapshot
{
block
:=
node
.
getBlockByNumber
(
blockNumber
)
return
node
.
getSnapshotAtHash
(
block
.
Hash
())
}
func
(
node
*
Node
)
getSigners
()
(
signers
[]
string
)
{
var
s
[]
common
.
Address
node
.
Call
(
&
s
,
"clique_getSigners"
,
nil
)
for
_
,
signer
:=
range
s
{
signers
=
append
(
signers
,
toHex
(
signer
.
Bytes
()))
}
return
}
func
(
node
*
Node
)
getSignersAtHash
(
hash
common
.
Hash
)
(
signers
[]
string
)
{
var
s
[]
common
.
Address
node
.
Call
(
&
signers
,
"clique_getSignersAtHash"
,
hash
)
for
_
,
signer
:=
range
s
{
signers
=
append
(
signers
,
toHex
(
signer
.
Bytes
()))
}
return
}
func
(
node
*
Node
)
getSignersAtBlock
(
blockNumber
int64
)
[]
string
{
block
:=
node
.
getBlockByNumber
(
blockNumber
)
return
node
.
getSignersAtHash
(
block
.
Hash
())
}
func
(
node
*
Node
)
getVotes
(
blockNumber
int64
)
(
votes
Proposals
)
{
var
(
snapshot
Snapshot
)
if
blockNumber
<
0
{
snapshot
=
node
.
getSnapshot
()
}
else
{
snapshot
=
node
.
getSnapshotAtBlock
(
blockNumber
)
}
votes
.
BlockNumber
=
int64
(
snapshot
.
Number
)
for
signer
:=
range
snapshot
.
Signers
{
votes
.
Signers
=
append
(
votes
.
Signers
,
toHex
(
signer
[
:
]))
sort
.
Strings
(
votes
.
Signers
)
}
for
proposal
:=
range
snapshot
.
Tally
{
votes
.
Proposals
=
append
(
votes
.
Proposals
,
toHex
(
proposal
[
:
]))
}
votes
.
Votes
=
make
(
map
[
string
]
map
[
string
]
*
bool
)
votes
.
Tally
=
make
(
map
[
string
]
*
Tally
)
for
_
,
v
:=
range
snapshot
.
Votes
{
proposal
:=
toHex
(
v
.
Address
[
:
])
signer
:=
toHex
(
v
.
Signer
[
:
])
if
votes
.
Votes
[
proposal
]
==
nil
{
votes
.
Votes
[
proposal
]
=
make
(
map
[
string
]
*
bool
)
for
_
,
signer
:=
range
votes
.
Signers
{
votes
.
Votes
[
proposal
][
signer
]
=
nil
}
votes
.
Tally
[
proposal
]
=
&
Tally
{
0
,
0
,
len
(
votes
.
Signers
)}
}
votes
.
Votes
[
proposal
][
signer
]
=
&
v
.
Authorize
if
v
.
Authorize
{
votes
.
Tally
[
proposal
]
.
True
+=
1
}
else
{
votes
.
Tally
[
proposal
]
.
False
+=
1
}
votes
.
Tally
[
proposal
]
.
Null
-=
1
}
return
}
func
(
node
*
Node
)
sealersStatus
()
map
[
string
]
int64
{
status
:=
make
(
map
[
string
]
int64
)
for
_
,
address
:=
range
node
.
getSigners
()
{
status
[
address
]
=
-
1
}
notSeen
:=
int64
(
len
(
status
))
block
:=
node
.
getBlockByNumber
(
-
1
)
blockNumber
:=
block
.
Number
.
Int64
()
until
:=
blockNumber
-
5
*
notSeen
for
notSeen
>
0
{
signer
,
_
:=
getSigner
(
&
block
)
if
status
[
signer
]
==
-
1
{
status
[
signer
]
=
block
.
Number
.
Int64
()
notSeen
--
}
if
blockNumber
==
until
{
break
}
blockNumber
--
block
=
node
.
getBlockByNumber
(
blockNumber
)
}
return
status
}
func
printDebug
(
msg
string
)
{
ptr
,
_
,
_
,
_
:=
runtime
.
Caller
(
1
)
fmt
.
Printf
(
"%v: %v
\n
"
,
msg
,
runtime
.
FuncForPC
(
ptr
)
.
Name
())
}
func
(
node
*
Node
)
getSealerInception
(
address
string
)
(
since
int64
)
{
if
signers
:=
node
.
getSigners
();
!
contains
(
signers
,
address
)
{
return
-
1
}
lo
:=
int64
(
0
)
hi
:=
node
.
blockNumber
()
for
lo
<
hi
{
mid
:=
lo
+
(
hi
-
lo
)
/
2
signers
:=
node
.
getSignersAtBlock
(
mid
)
if
contains
(
signers
,
address
)
{
hi
=
mid
}
else
{
lo
=
mid
+
1
}
}
return
hi
}
func
min
(
a
,
b
int64
)
int64
{
if
a
<
b
{
return
a
}
return
b
}
func
(
node
*
Node
)
getSignerFirstBlock
(
signer
string
,
since
int64
,
until
int64
)
(
blockNumber
int64
)
{
if
since
<
0
{
return
-
1
}
//snapshot := node.getSnapshotAtBlock(since)
var
count
int64
=
20
// first, we look close to the inception
if
blockNumber
=
node
.
searchSnapshotForward
(
since
,
signer
,
count
);
blockNumber
>
0
{
return
}
since
+=
count
n
:=
min
(
10
,
(
until
-
since
)
/
count
+
1
)
// number of goroutines
ch
:=
make
(
chan
int64
)
for
i
:=
int64
(
0
);
i
<
n
;
i
++
{
go
func
()
{
for
blockNumber
:=
<-
ch
;
blockNumber
>
0
;
blockNumber
=
<-
ch
{
cnt
:=
min
(
count
,
until
-
blockNumber
+
1
)
if
found
:=
node
.
searchSnapshotForward
(
blockNumber
,
signer
,
cnt
);
found
>
0
{
ch
<-
found
}
}
ch
<-
(
-
1
)
}()
}
for
{
select
{
case
ch
<-
since
:
switch
{
case
since
<
0
:
continue
case
since
+
count
<
until
:
since
+=
count
default
:
since
=
-
1
//we have exhausted the search space
}
case
found
:=
<-
ch
:
switch
{
case
found
<
0
:
n
--
// a goroutine has ended
if
n
==
0
{
// all goroutines have ended
return
}
case
blockNumber
<
0
:
blockNumber
=
found
// first time we see this signer
since
=
-
1
// Notify everyone
case
found
<
blockNumber
:
blockNumber
=
found
// found an earlier block
}
}
}
}
func
(
node
*
Node
)
getSignerFirstBlock_
(
signer
string
,
since
int64
,
until
int64
)
(
blockNumber
int64
)
{
if
since
<
0
{
return
-
1
}
last
:=
since
for
i
:=
since
;
;
{
snapshot
:=
node
.
getSnapshotAtBlock
(
i
)
n
:=
int64
(
len
(
snapshot
.
Recents
))
if
int64
(
snapshot
.
Number
)
-
n
>
last
{
i
--
continue
}
for
b
,
s
:=
range
snapshot
.
Recents
{
if
toHex
(
s
[
:
])
==
signer
{
return
int64
(
b
)
}
}
if
i
>=
until
{
return
-
1
}
last
=
i
i
+=
n
}
}
func
(
node
*
Node
)
searchSnapshot
(
blockNumber
int64
,
signer
string
,
count
int64
,
forward
bool
)
(
found
int64
)
{
found
=
-
1
for
count
>
0
{
snapshot
:=
node
.
getSnapshotAtBlock
(
blockNumber
+
count
-
1
)
for
b
,
s
:=
range
snapshot
.
Recents
{
if
toHex
(
s
[
:
])
==
signer
{
found
=
int64
(
b
)
if
!
forward
{
return
}
}
}
count
-=
int64
(
len
(
snapshot
.
Recents
))
}
return
}
func
(
node
*
Node
)
searchSnapshotForward
(
blockNumber
int64
,
signer
string
,
count
int64
)
(
found
int64
)
{
found
=
-
1
for
count
>
0
{
snapshot
:=
node
.
getSnapshotAtBlock
(
blockNumber
+
count
-
1
)
for
b
,
s
:=
range
snapshot
.
Recents
{
if
toHex
(
s
[
:
])
==
signer
{
found
=
int64
(
b
)
}
}
count
-=
int64
(
len
(
snapshot
.
Recents
))
}
return
}
func
(
node
*
Node
)
searchSnapshotBackward
(
blockNumber
int64
,
signer
string
,
count
int64
)
(
found
int64
)
{
found
=
-
1
for
i
:=
int64
(
0
);
i
<
count
;
{
snapshot
:=
node
.
getSnapshotAtBlock
(
blockNumber
-
i
)
for
b
,
s
:=
range
snapshot
.
Recents
{
if
toHex
(
s
[
:
])
==
signer
{
return
int64
(
b
)
}
}
i
+=
int64
(
len
(
snapshot
.
Recents
))
}
return
}
func
(
node
*
Node
)
getSignerLastBlock
(
signer
string
,
since
int64
,
until
int64
)
(
blockNumber
int64
)
{
if
since
<
0
{
return
-
1
}
var
count
int64
=
20
// first, we look close to the last block
if
blockNumber
=
node
.
searchSnapshotBackward
(
until
,
signer
,
count
);
blockNumber
>
0
{
return
}
until
-=
count
n
:=
min
(
10
,
(
until
-
since
)
/
count
+
1
)
// number of goroutines
ch
:=
make
(
chan
int64
)
for
i
:=
int64
(
0
);
i
<
n
;
i
++
{
go
func
()
{
for
blockNumber
:=
<-
ch
;
blockNumber
>
0
;
blockNumber
=
<-
ch
{
cnt
:=
min
(
count
,
blockNumber
-
since
+
1
)
if
found
:=
node
.
searchSnapshotBackward
(
blockNumber
,
signer
,
cnt
);
found
>
0
{
ch
<-
found
}
}
ch
<-
(
-
1
)
}()
}
for
{
select
{
case
ch
<-
since
:
switch
{
case
until
<
0
:
continue
case
until
-
count
>
since
:
until
-=
count
default
:
until
=
-
1
//we have exhausted the search space
}
case
found
:=
<-
ch
:
switch
{
case
found
<
0
:
n
--
// a goroutine has ended
if
n
==
0
{
// all goroutines have ended
return
}
case
blockNumber
<
0
:
blockNumber
=
found
// first time we see this signer
until
=
-
1
// Notify everyone
case
found
>
blockNumber
:
blockNumber
=
found
// found a later block
}
}
}
}
func
(
node
*
Node
)
getSignerLastBlock__
(
signer
string
,
since
int64
,
until
int64
)
(
blockNumber
int64
)
{
if
since
<
0
{
return
-
1
}
for
i
:=
until
;
i
>=
since
;
{
snapshot
:=
node
.
getSnapshotAtBlock
(
i
)
for
b
,
s
:=
range
snapshot
.
Recents
{
if
toHex
(
s
[
:
])
==
signer
{
return
int64
(
b
)
}
}
i
-=
int64
(
len
(
snapshot
.
Recents
))
}
return
-
1
}
func
(
node
*
Node
)
getSignerLastBlock_
(
signer
string
,
since
int64
,
until
int64
)
(
blockNumber
int64
)
{
if
since
<
0
{
return
-
1
}
for
i
:=
until
;
i
>=
since
;
i
--
{
if
signer
==
node
.
getBlockSigner
(
i
)
{
return
i
}
}
return
-
1
}
type
SealerInfo
struct
{
Address
string
CurrentBlock
int64
Since
int64
FirstBlock
int64
LastBlock
int64
}
func
(
node
*
Node
)
sealerInfo
(
sealer
string
)
(
info
SealerInfo
,
err
error
)
{
info
.
Address
=
sealer
info
.
CurrentBlock
=
node
.
blockNumber
()
info
.
Since
=
node
.
getSealerInception
(
sealer
)
if
info
.
Since
==
-
1
{
return
info
,
fmt
.
Errorf
(
"%q is not a sealer"
,
sealer
)
}
info
.
FirstBlock
=
node
.
getSignerFirstBlock
(
sealer
,
info
.
Since
+
1
,
info
.
CurrentBlock
)
info
.
LastBlock
=
node
.
getSignerLastBlock
(
sealer
,
info
.
FirstBlock
,
info
.
CurrentBlock
)
return
}
func
printVotes
(
node
*
Node
,
useJson
bool
)
{
votes
:=
node
.
getVotes
(
-
1
)
if
useJson
{
if
useJson
{
v
,
err
:=
json
.
MarshalIndent
(
votes
,
""
,
" "
)
v
,
err
:=
json
.
MarshalIndent
(
votes
,
""
,
" "
)
c
heck
(
err
)
util
.
C
heck
(
err
)
fmt
.
Println
(
string
(
v
))
fmt
.
Println
(
string
(
v
))
return
return
}
}
...
@@ -481,18 +47,18 @@ func printVotes(node *Node, useJson bool) {
...
@@ -481,18 +47,18 @@ func printVotes(node *Node, useJson bool) {
}
}
func
printSealerInfo
(
node
*
Node
,
sealer
string
)
{
func
printSealerInfo
(
node
*
Node
,
sealer
string
)
{
info
,
err
:=
node
.
s
ealerInfo
(
sealer
)
info
,
err
:=
node
.
S
ealerInfo
(
sealer
)
c
heck
(
err
)
util
.
C
heck
(
err
)
v
,
err
:=
json
.
MarshalIndent
(
info
,
""
,
" "
)
v
,
err
:=
json
.
MarshalIndent
(
info
,
""
,
" "
)
c
heck
(
err
)
util
.
C
heck
(
err
)
fmt
.
Println
(
string
(
v
))
fmt
.
Println
(
string
(
v
))
}
}
func
printSealers
(
node
*
Node
,
useJson
bool
)
{
func
printSealers
(
node
*
Node
,
useJson
bool
)
{
sealers
:=
node
.
s
ealersStatus
()
sealers
:=
node
.
S
ealersStatus
()
if
useJson
{
if
useJson
{
v
,
err
:=
json
.
MarshalIndent
(
sealers
,
""
,
" "
)
v
,
err
:=
json
.
MarshalIndent
(
sealers
,
""
,
" "
)
c
heck
(
err
)
util
.
C
heck
(
err
)
fmt
.
Println
(
string
(
v
))
fmt
.
Println
(
string
(
v
))
return
return
}
}
...
@@ -507,48 +73,6 @@ func printSealers(node *Node, useJson bool) {
...
@@ -507,48 +73,6 @@ func printSealers(node *Node, useJson bool) {
}
}
}
}
func
sigHash
(
header
*
types
.
Header
)
(
hash
common
.
Hash
)
{
hasher
:=
sha3
.
NewKeccak256
()
rlp
.
Encode
(
hasher
,
[]
interface
{}{
header
.
ParentHash
,
header
.
UncleHash
,
header
.
Coinbase
,
header
.
Root
,
header
.
TxHash
,
header
.
ReceiptHash
,
header
.
Bloom
,
header
.
Difficulty
,
header
.
Number
,
header
.
GasLimit
,
header
.
GasUsed
,
header
.
Time
,
header
.
Extra
[
:
len
(
header
.
Extra
)
-
65
],
// Yes, this will panic if extra is too short
header
.
MixDigest
,
header
.
Nonce
,
})
hasher
.
Sum
(
hash
[
:
0
])
return
hash
}
func
Dial
(
url
string
)
*
Node
{
client
,
err
:=
rpc
.
Dial
(
url
)
check
(
err
)
return
(
*
Node
)(
client
)
}
func
(
node
*
Node
)
Close
()
{
(
*
rpc
.
Client
)(
node
)
.
Close
()
}
func
contains
(
slice
[]
string
,
s
string
)
bool
{
for
_
,
x
:=
range
slice
{
if
x
==
s
{
return
true
}
}
return
false
}
func
main
()
{
func
main
()
{
var
(
var
(
...
@@ -572,7 +96,7 @@ func main() {
...
@@ -572,7 +96,7 @@ func main() {
if
len
(
os
.
Args
)
>
1
{
if
len
(
os
.
Args
)
>
1
{
command
=
os
.
Args
[
1
]
command
=
os
.
Args
[
1
]
}
}
if
!
c
ontains
(
commands
,
command
)
{
if
!
util
.
C
ontains
(
commands
,
command
)
{
fmt
.
Fprintf
(
os
.
Stderr
,
"Uso: %v <%v> [opciones]
\n
"
,
path
.
Base
(
os
.
Args
[
0
]),
strings
.
Join
(
commands
,
"|"
))
fmt
.
Fprintf
(
os
.
Stderr
,
"Uso: %v <%v> [opciones]
\n
"
,
path
.
Base
(
os
.
Args
[
0
]),
strings
.
Join
(
commands
,
"|"
))
fmt
.
Fprintf
(
os
.
Stderr
,
"For help: %v <command> -h
\n
"
,
path
.
Base
(
os
.
Args
[
0
]))
fmt
.
Fprintf
(
os
.
Stderr
,
"For help: %v <command> -h
\n
"
,
path
.
Base
(
os
.
Args
[
0
]))
os
.
Exit
(
1
)
os
.
Exit
(
1
)
...
@@ -587,7 +111,7 @@ func main() {
...
@@ -587,7 +111,7 @@ func main() {
flags
.
PrintDefaults
()
flags
.
PrintDefaults
()
return
return
}
}
node
:=
Dial
(
url
)
node
:=
bfa
.
Dial
(
url
)
defer
node
.
Close
()
defer
node
.
Close
()
switch
command
{
switch
command
{
case
"sealers"
:
case
"sealers"
:
...
...
This diff is collapsed.
Click to expand it.
bfa_client/src/util/util.go
0 → 100644
+
42
−
0
View file @
fd6f11a0
package
util
import
(
"fmt"
"runtime"
)
func
Contains
(
slice
[]
string
,
s
string
)
bool
{
for
_
,
x
:=
range
slice
{
if
x
==
s
{
return
true
}
}
return
false
}
func
Check
(
err
error
)
{
if
err
!=
nil
{
panic
(
err
.
Error
())
}
}
func
ToHex
(
b
[]
byte
)
string
{
return
fmt
.
Sprintf
(
"0x%02x"
,
b
)
}
func
PrintDebug
(
prefix
,
suffix
string
)
{
ptr
,
_
,
_
,
_
:=
runtime
.
Caller
(
1
)
fmt
.
Printf
(
"%v: %v%v
\n
"
,
prefix
,
runtime
.
FuncForPC
(
ptr
)
.
Name
(),
suffix
)
}
func
Min
(
a
,
b
int64
)
int64
{
if
a
<
b
{
return
a
}
return
b
}
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment