forked from TrueCloudLab/frostfs-contract
[#19] alphabet: Check epoch value in Vote method
Signed-off-by: Alex Vanin <alexey@nspcc.ru>
This commit is contained in:
parent
24b7bc5c77
commit
a8d55d9166
8 changed files with 182 additions and 134 deletions
|
@ -2,7 +2,6 @@ package alphabetcontract
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/nspcc-dev/neo-go/pkg/interop/binary"
|
"github.com/nspcc-dev/neo-go/pkg/interop/binary"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/interop/blockchain"
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/interop/contract"
|
"github.com/nspcc-dev/neo-go/pkg/interop/contract"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/interop/crypto"
|
"github.com/nspcc-dev/neo-go/pkg/interop/crypto"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/interop/engine"
|
"github.com/nspcc-dev/neo-go/pkg/interop/engine"
|
||||||
|
@ -17,9 +16,9 @@ type (
|
||||||
}
|
}
|
||||||
|
|
||||||
ballot struct {
|
ballot struct {
|
||||||
id []byte // id of the voting decision
|
id []byte // hash of validators list
|
||||||
n [][]byte // already voted inner ring nodes
|
n [][]byte // already voted inner ring nodes
|
||||||
block int // block with the last vote
|
height int // height is an neofs epoch when ballot was registered
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -35,8 +34,6 @@ const (
|
||||||
|
|
||||||
netmapContractKey = "netmapScriptHash"
|
netmapContractKey = "netmapScriptHash"
|
||||||
|
|
||||||
blockDiff = 20 // amount of blocks when ballot get discarded
|
|
||||||
|
|
||||||
threshold = totalAlphabetContracts * 2 / 3 + 1
|
threshold = totalAlphabetContracts * 2 / 3 + 1
|
||||||
voteKey = "ballots"
|
voteKey = "ballots"
|
||||||
|
|
||||||
|
@ -91,6 +88,11 @@ func irList() []irNode {
|
||||||
return engine.AppCall(netmapContractAddr, "innerRingList").([]irNode)
|
return engine.AppCall(netmapContractAddr, "innerRingList").([]irNode)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func currentEpoch() int {
|
||||||
|
netmapContractAddr := storage.Get(ctx, netmapContractKey).([]byte)
|
||||||
|
return engine.AppCall(netmapContractAddr, "epoch").(int)
|
||||||
|
}
|
||||||
|
|
||||||
func checkPermission(ir []irNode) bool {
|
func checkPermission(ir []irNode) bool {
|
||||||
if len(ir) <= index {
|
if len(ir) <= index {
|
||||||
return false
|
return false
|
||||||
|
@ -153,8 +155,13 @@ func Vote(epoch int, candidates [][]byte) {
|
||||||
panic("invalid invoker")
|
panic("invalid invoker")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
curEpoch := currentEpoch()
|
||||||
|
if epoch != curEpoch {
|
||||||
|
panic("invalid epoch")
|
||||||
|
}
|
||||||
|
|
||||||
id := voteID(epoch, candidates)
|
id := voteID(epoch, candidates)
|
||||||
n := vote(ctx, id, key)
|
n := vote(ctx, curEpoch, id, key)
|
||||||
|
|
||||||
if n >= threshold {
|
if n >= threshold {
|
||||||
candidate := candidates[index%len(candidates)]
|
candidate := candidates[index%len(candidates)]
|
||||||
|
@ -178,12 +185,11 @@ func Name() string {
|
||||||
return name
|
return name
|
||||||
}
|
}
|
||||||
|
|
||||||
func vote(ctx storage.Context, id, from []byte) int {
|
func vote(ctx storage.Context, epoch int, id, from []byte) int {
|
||||||
var (
|
var (
|
||||||
newCandidates []ballot
|
newCandidates []ballot
|
||||||
candidates = getBallots(ctx)
|
candidates = getBallots(ctx)
|
||||||
found = -1
|
found = -1
|
||||||
blockHeight = blockchain.GetHeight()
|
|
||||||
)
|
)
|
||||||
|
|
||||||
for i := 0; i < len(candidates); i++ {
|
for i := 0; i < len(candidates); i++ {
|
||||||
|
@ -198,12 +204,12 @@ func vote(ctx storage.Context, id, from []byte) int {
|
||||||
}
|
}
|
||||||
|
|
||||||
voters = append(voters, from)
|
voters = append(voters, from)
|
||||||
cnd = ballot{id: id, n: voters, block: blockHeight}
|
cnd = ballot{id: id, n: voters, height: epoch}
|
||||||
found = len(voters)
|
found = len(voters)
|
||||||
}
|
}
|
||||||
|
|
||||||
// do not add old ballots, they are invalid
|
// add only valid ballots with current epochs
|
||||||
if blockHeight-cnd.block <= blockDiff {
|
if cnd.height == epoch {
|
||||||
newCandidates = append(newCandidates, cnd)
|
newCandidates = append(newCandidates, cnd)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -211,9 +217,9 @@ func vote(ctx storage.Context, id, from []byte) int {
|
||||||
if found < 0 {
|
if found < 0 {
|
||||||
voters := [][]byte{from}
|
voters := [][]byte{from}
|
||||||
newCandidates = append(newCandidates, ballot{
|
newCandidates = append(newCandidates, ballot{
|
||||||
id: id,
|
id: id,
|
||||||
n: voters,
|
n: voters,
|
||||||
block: blockHeight})
|
height: epoch})
|
||||||
found = 1
|
found = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,6 @@ package alphabetcontract
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/nspcc-dev/neo-go/pkg/interop/binary"
|
"github.com/nspcc-dev/neo-go/pkg/interop/binary"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/interop/blockchain"
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/interop/contract"
|
"github.com/nspcc-dev/neo-go/pkg/interop/contract"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/interop/crypto"
|
"github.com/nspcc-dev/neo-go/pkg/interop/crypto"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/interop/engine"
|
"github.com/nspcc-dev/neo-go/pkg/interop/engine"
|
||||||
|
@ -17,9 +16,9 @@ type (
|
||||||
}
|
}
|
||||||
|
|
||||||
ballot struct {
|
ballot struct {
|
||||||
id []byte // id of the voting decision
|
id []byte // hash of validators list
|
||||||
n [][]byte // already voted inner ring nodes
|
n [][]byte // already voted inner ring nodes
|
||||||
block int // block with the last vote
|
height int // height is an neofs epoch when ballot was registered
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -35,9 +34,7 @@ const (
|
||||||
|
|
||||||
netmapContractKey = "netmapScriptHash"
|
netmapContractKey = "netmapScriptHash"
|
||||||
|
|
||||||
blockDiff = 20 // amount of blocks when ballot get discarded
|
threshold = totalAlphabetContracts * 2 / 3 + 1
|
||||||
|
|
||||||
threshold = totalAlphabetContracts*2/3 + 1
|
|
||||||
voteKey = "ballots"
|
voteKey = "ballots"
|
||||||
|
|
||||||
totalAlphabetContracts = 7
|
totalAlphabetContracts = 7
|
||||||
|
@ -91,6 +88,11 @@ func irList() []irNode {
|
||||||
return engine.AppCall(netmapContractAddr, "innerRingList").([]irNode)
|
return engine.AppCall(netmapContractAddr, "innerRingList").([]irNode)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func currentEpoch() int {
|
||||||
|
netmapContractAddr := storage.Get(ctx, netmapContractKey).([]byte)
|
||||||
|
return engine.AppCall(netmapContractAddr, "epoch").(int)
|
||||||
|
}
|
||||||
|
|
||||||
func checkPermission(ir []irNode) bool {
|
func checkPermission(ir []irNode) bool {
|
||||||
if len(ir) <= index {
|
if len(ir) <= index {
|
||||||
return false
|
return false
|
||||||
|
@ -153,8 +155,13 @@ func Vote(epoch int, candidates [][]byte) {
|
||||||
panic("invalid invoker")
|
panic("invalid invoker")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
curEpoch := currentEpoch()
|
||||||
|
if epoch != curEpoch {
|
||||||
|
panic("invalid epoch")
|
||||||
|
}
|
||||||
|
|
||||||
id := voteID(epoch, candidates)
|
id := voteID(epoch, candidates)
|
||||||
n := vote(ctx, id, key)
|
n := vote(ctx, curEpoch, id, key)
|
||||||
|
|
||||||
if n >= threshold {
|
if n >= threshold {
|
||||||
candidate := candidates[index%len(candidates)]
|
candidate := candidates[index%len(candidates)]
|
||||||
|
@ -178,12 +185,11 @@ func Name() string {
|
||||||
return name
|
return name
|
||||||
}
|
}
|
||||||
|
|
||||||
func vote(ctx storage.Context, id, from []byte) int {
|
func vote(ctx storage.Context, epoch int, id, from []byte) int {
|
||||||
var (
|
var (
|
||||||
newCandidates []ballot
|
newCandidates []ballot
|
||||||
candidates = getBallots(ctx)
|
candidates = getBallots(ctx)
|
||||||
found = -1
|
found = -1
|
||||||
blockHeight = blockchain.GetHeight()
|
|
||||||
)
|
)
|
||||||
|
|
||||||
for i := 0; i < len(candidates); i++ {
|
for i := 0; i < len(candidates); i++ {
|
||||||
|
@ -198,12 +204,12 @@ func vote(ctx storage.Context, id, from []byte) int {
|
||||||
}
|
}
|
||||||
|
|
||||||
voters = append(voters, from)
|
voters = append(voters, from)
|
||||||
cnd = ballot{id: id, n: voters, block: blockHeight}
|
cnd = ballot{id: id, n: voters, height: epoch}
|
||||||
found = len(voters)
|
found = len(voters)
|
||||||
}
|
}
|
||||||
|
|
||||||
// do not add old ballots, they are invalid
|
// add only valid ballots with current epochs
|
||||||
if blockHeight-cnd.block <= blockDiff {
|
if cnd.height == epoch {
|
||||||
newCandidates = append(newCandidates, cnd)
|
newCandidates = append(newCandidates, cnd)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -211,9 +217,9 @@ func vote(ctx storage.Context, id, from []byte) int {
|
||||||
if found < 0 {
|
if found < 0 {
|
||||||
voters := [][]byte{from}
|
voters := [][]byte{from}
|
||||||
newCandidates = append(newCandidates, ballot{
|
newCandidates = append(newCandidates, ballot{
|
||||||
id: id,
|
id: id,
|
||||||
n: voters,
|
n: voters,
|
||||||
block: blockHeight})
|
height: epoch})
|
||||||
found = 1
|
found = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -259,7 +265,7 @@ func bytesEqual(a []byte, b []byte) bool {
|
||||||
|
|
||||||
func voteID(epoch interface{}, args [][]byte) []byte {
|
func voteID(epoch interface{}, args [][]byte) []byte {
|
||||||
var (
|
var (
|
||||||
result []byte
|
result []byte
|
||||||
epochBytes = epoch.([]byte)
|
epochBytes = epoch.([]byte)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,6 @@ package alphabetcontract
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/nspcc-dev/neo-go/pkg/interop/binary"
|
"github.com/nspcc-dev/neo-go/pkg/interop/binary"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/interop/blockchain"
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/interop/contract"
|
"github.com/nspcc-dev/neo-go/pkg/interop/contract"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/interop/crypto"
|
"github.com/nspcc-dev/neo-go/pkg/interop/crypto"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/interop/engine"
|
"github.com/nspcc-dev/neo-go/pkg/interop/engine"
|
||||||
|
@ -17,9 +16,9 @@ type (
|
||||||
}
|
}
|
||||||
|
|
||||||
ballot struct {
|
ballot struct {
|
||||||
id []byte // id of the voting decision
|
id []byte // hash of validators list
|
||||||
n [][]byte // already voted inner ring nodes
|
n [][]byte // already voted inner ring nodes
|
||||||
block int // block with the last vote
|
height int // height is an neofs epoch when ballot was registered
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -35,9 +34,7 @@ const (
|
||||||
|
|
||||||
netmapContractKey = "netmapScriptHash"
|
netmapContractKey = "netmapScriptHash"
|
||||||
|
|
||||||
blockDiff = 20 // amount of blocks when ballot get discarded
|
threshold = totalAlphabetContracts * 2 / 3 + 1
|
||||||
|
|
||||||
threshold = totalAlphabetContracts*2/3 + 1
|
|
||||||
voteKey = "ballots"
|
voteKey = "ballots"
|
||||||
|
|
||||||
totalAlphabetContracts = 7
|
totalAlphabetContracts = 7
|
||||||
|
@ -91,6 +88,11 @@ func irList() []irNode {
|
||||||
return engine.AppCall(netmapContractAddr, "innerRingList").([]irNode)
|
return engine.AppCall(netmapContractAddr, "innerRingList").([]irNode)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func currentEpoch() int {
|
||||||
|
netmapContractAddr := storage.Get(ctx, netmapContractKey).([]byte)
|
||||||
|
return engine.AppCall(netmapContractAddr, "epoch").(int)
|
||||||
|
}
|
||||||
|
|
||||||
func checkPermission(ir []irNode) bool {
|
func checkPermission(ir []irNode) bool {
|
||||||
if len(ir) <= index {
|
if len(ir) <= index {
|
||||||
return false
|
return false
|
||||||
|
@ -153,8 +155,13 @@ func Vote(epoch int, candidates [][]byte) {
|
||||||
panic("invalid invoker")
|
panic("invalid invoker")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
curEpoch := currentEpoch()
|
||||||
|
if epoch != curEpoch {
|
||||||
|
panic("invalid epoch")
|
||||||
|
}
|
||||||
|
|
||||||
id := voteID(epoch, candidates)
|
id := voteID(epoch, candidates)
|
||||||
n := vote(ctx, id, key)
|
n := vote(ctx, curEpoch, id, key)
|
||||||
|
|
||||||
if n >= threshold {
|
if n >= threshold {
|
||||||
candidate := candidates[index%len(candidates)]
|
candidate := candidates[index%len(candidates)]
|
||||||
|
@ -178,12 +185,11 @@ func Name() string {
|
||||||
return name
|
return name
|
||||||
}
|
}
|
||||||
|
|
||||||
func vote(ctx storage.Context, id, from []byte) int {
|
func vote(ctx storage.Context, epoch int, id, from []byte) int {
|
||||||
var (
|
var (
|
||||||
newCandidates []ballot
|
newCandidates []ballot
|
||||||
candidates = getBallots(ctx)
|
candidates = getBallots(ctx)
|
||||||
found = -1
|
found = -1
|
||||||
blockHeight = blockchain.GetHeight()
|
|
||||||
)
|
)
|
||||||
|
|
||||||
for i := 0; i < len(candidates); i++ {
|
for i := 0; i < len(candidates); i++ {
|
||||||
|
@ -198,12 +204,12 @@ func vote(ctx storage.Context, id, from []byte) int {
|
||||||
}
|
}
|
||||||
|
|
||||||
voters = append(voters, from)
|
voters = append(voters, from)
|
||||||
cnd = ballot{id: id, n: voters, block: blockHeight}
|
cnd = ballot{id: id, n: voters, height: epoch}
|
||||||
found = len(voters)
|
found = len(voters)
|
||||||
}
|
}
|
||||||
|
|
||||||
// do not add old ballots, they are invalid
|
// add only valid ballots with current epochs
|
||||||
if blockHeight-cnd.block <= blockDiff {
|
if cnd.height == epoch {
|
||||||
newCandidates = append(newCandidates, cnd)
|
newCandidates = append(newCandidates, cnd)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -211,9 +217,9 @@ func vote(ctx storage.Context, id, from []byte) int {
|
||||||
if found < 0 {
|
if found < 0 {
|
||||||
voters := [][]byte{from}
|
voters := [][]byte{from}
|
||||||
newCandidates = append(newCandidates, ballot{
|
newCandidates = append(newCandidates, ballot{
|
||||||
id: id,
|
id: id,
|
||||||
n: voters,
|
n: voters,
|
||||||
block: blockHeight})
|
height: epoch})
|
||||||
found = 1
|
found = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -259,7 +265,7 @@ func bytesEqual(a []byte, b []byte) bool {
|
||||||
|
|
||||||
func voteID(epoch interface{}, args [][]byte) []byte {
|
func voteID(epoch interface{}, args [][]byte) []byte {
|
||||||
var (
|
var (
|
||||||
result []byte
|
result []byte
|
||||||
epochBytes = epoch.([]byte)
|
epochBytes = epoch.([]byte)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,6 @@ package alphabetcontract
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/nspcc-dev/neo-go/pkg/interop/binary"
|
"github.com/nspcc-dev/neo-go/pkg/interop/binary"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/interop/blockchain"
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/interop/contract"
|
"github.com/nspcc-dev/neo-go/pkg/interop/contract"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/interop/crypto"
|
"github.com/nspcc-dev/neo-go/pkg/interop/crypto"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/interop/engine"
|
"github.com/nspcc-dev/neo-go/pkg/interop/engine"
|
||||||
|
@ -17,9 +16,9 @@ type (
|
||||||
}
|
}
|
||||||
|
|
||||||
ballot struct {
|
ballot struct {
|
||||||
id []byte // id of the voting decision
|
id []byte // hash of validators list
|
||||||
n [][]byte // already voted inner ring nodes
|
n [][]byte // already voted inner ring nodes
|
||||||
block int // block with the last vote
|
height int // height is an neofs epoch when ballot was registered
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -35,9 +34,7 @@ const (
|
||||||
|
|
||||||
netmapContractKey = "netmapScriptHash"
|
netmapContractKey = "netmapScriptHash"
|
||||||
|
|
||||||
blockDiff = 20 // amount of blocks when ballot get discarded
|
threshold = totalAlphabetContracts * 2 / 3 + 1
|
||||||
|
|
||||||
threshold = totalAlphabetContracts*2/3 + 1
|
|
||||||
voteKey = "ballots"
|
voteKey = "ballots"
|
||||||
|
|
||||||
totalAlphabetContracts = 7
|
totalAlphabetContracts = 7
|
||||||
|
@ -91,6 +88,11 @@ func irList() []irNode {
|
||||||
return engine.AppCall(netmapContractAddr, "innerRingList").([]irNode)
|
return engine.AppCall(netmapContractAddr, "innerRingList").([]irNode)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func currentEpoch() int {
|
||||||
|
netmapContractAddr := storage.Get(ctx, netmapContractKey).([]byte)
|
||||||
|
return engine.AppCall(netmapContractAddr, "epoch").(int)
|
||||||
|
}
|
||||||
|
|
||||||
func checkPermission(ir []irNode) bool {
|
func checkPermission(ir []irNode) bool {
|
||||||
if len(ir) <= index {
|
if len(ir) <= index {
|
||||||
return false
|
return false
|
||||||
|
@ -153,8 +155,13 @@ func Vote(epoch int, candidates [][]byte) {
|
||||||
panic("invalid invoker")
|
panic("invalid invoker")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
curEpoch := currentEpoch()
|
||||||
|
if epoch != curEpoch {
|
||||||
|
panic("invalid epoch")
|
||||||
|
}
|
||||||
|
|
||||||
id := voteID(epoch, candidates)
|
id := voteID(epoch, candidates)
|
||||||
n := vote(ctx, id, key)
|
n := vote(ctx, curEpoch, id, key)
|
||||||
|
|
||||||
if n >= threshold {
|
if n >= threshold {
|
||||||
candidate := candidates[index%len(candidates)]
|
candidate := candidates[index%len(candidates)]
|
||||||
|
@ -178,12 +185,11 @@ func Name() string {
|
||||||
return name
|
return name
|
||||||
}
|
}
|
||||||
|
|
||||||
func vote(ctx storage.Context, id, from []byte) int {
|
func vote(ctx storage.Context, epoch int, id, from []byte) int {
|
||||||
var (
|
var (
|
||||||
newCandidates []ballot
|
newCandidates []ballot
|
||||||
candidates = getBallots(ctx)
|
candidates = getBallots(ctx)
|
||||||
found = -1
|
found = -1
|
||||||
blockHeight = blockchain.GetHeight()
|
|
||||||
)
|
)
|
||||||
|
|
||||||
for i := 0; i < len(candidates); i++ {
|
for i := 0; i < len(candidates); i++ {
|
||||||
|
@ -198,12 +204,12 @@ func vote(ctx storage.Context, id, from []byte) int {
|
||||||
}
|
}
|
||||||
|
|
||||||
voters = append(voters, from)
|
voters = append(voters, from)
|
||||||
cnd = ballot{id: id, n: voters, block: blockHeight}
|
cnd = ballot{id: id, n: voters, height: epoch}
|
||||||
found = len(voters)
|
found = len(voters)
|
||||||
}
|
}
|
||||||
|
|
||||||
// do not add old ballots, they are invalid
|
// add only valid ballots with current epochs
|
||||||
if blockHeight-cnd.block <= blockDiff {
|
if cnd.height == epoch {
|
||||||
newCandidates = append(newCandidates, cnd)
|
newCandidates = append(newCandidates, cnd)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -211,9 +217,9 @@ func vote(ctx storage.Context, id, from []byte) int {
|
||||||
if found < 0 {
|
if found < 0 {
|
||||||
voters := [][]byte{from}
|
voters := [][]byte{from}
|
||||||
newCandidates = append(newCandidates, ballot{
|
newCandidates = append(newCandidates, ballot{
|
||||||
id: id,
|
id: id,
|
||||||
n: voters,
|
n: voters,
|
||||||
block: blockHeight})
|
height: epoch})
|
||||||
found = 1
|
found = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -259,7 +265,7 @@ func bytesEqual(a []byte, b []byte) bool {
|
||||||
|
|
||||||
func voteID(epoch interface{}, args [][]byte) []byte {
|
func voteID(epoch interface{}, args [][]byte) []byte {
|
||||||
var (
|
var (
|
||||||
result []byte
|
result []byte
|
||||||
epochBytes = epoch.([]byte)
|
epochBytes = epoch.([]byte)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,6 @@ package alphabetcontract
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/nspcc-dev/neo-go/pkg/interop/binary"
|
"github.com/nspcc-dev/neo-go/pkg/interop/binary"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/interop/blockchain"
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/interop/contract"
|
"github.com/nspcc-dev/neo-go/pkg/interop/contract"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/interop/crypto"
|
"github.com/nspcc-dev/neo-go/pkg/interop/crypto"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/interop/engine"
|
"github.com/nspcc-dev/neo-go/pkg/interop/engine"
|
||||||
|
@ -17,9 +16,9 @@ type (
|
||||||
}
|
}
|
||||||
|
|
||||||
ballot struct {
|
ballot struct {
|
||||||
id []byte // id of the voting decision
|
id []byte // hash of validators list
|
||||||
n [][]byte // already voted inner ring nodes
|
n [][]byte // already voted inner ring nodes
|
||||||
block int // block with the last vote
|
height int // height is an neofs epoch when ballot was registered
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -35,9 +34,7 @@ const (
|
||||||
|
|
||||||
netmapContractKey = "netmapScriptHash"
|
netmapContractKey = "netmapScriptHash"
|
||||||
|
|
||||||
blockDiff = 20 // amount of blocks when ballot get discarded
|
threshold = totalAlphabetContracts * 2 / 3 + 1
|
||||||
|
|
||||||
threshold = totalAlphabetContracts*2/3 + 1
|
|
||||||
voteKey = "ballots"
|
voteKey = "ballots"
|
||||||
|
|
||||||
totalAlphabetContracts = 7
|
totalAlphabetContracts = 7
|
||||||
|
@ -91,6 +88,11 @@ func irList() []irNode {
|
||||||
return engine.AppCall(netmapContractAddr, "innerRingList").([]irNode)
|
return engine.AppCall(netmapContractAddr, "innerRingList").([]irNode)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func currentEpoch() int {
|
||||||
|
netmapContractAddr := storage.Get(ctx, netmapContractKey).([]byte)
|
||||||
|
return engine.AppCall(netmapContractAddr, "epoch").(int)
|
||||||
|
}
|
||||||
|
|
||||||
func checkPermission(ir []irNode) bool {
|
func checkPermission(ir []irNode) bool {
|
||||||
if len(ir) <= index {
|
if len(ir) <= index {
|
||||||
return false
|
return false
|
||||||
|
@ -153,8 +155,13 @@ func Vote(epoch int, candidates [][]byte) {
|
||||||
panic("invalid invoker")
|
panic("invalid invoker")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
curEpoch := currentEpoch()
|
||||||
|
if epoch != curEpoch {
|
||||||
|
panic("invalid epoch")
|
||||||
|
}
|
||||||
|
|
||||||
id := voteID(epoch, candidates)
|
id := voteID(epoch, candidates)
|
||||||
n := vote(ctx, id, key)
|
n := vote(ctx, curEpoch, id, key)
|
||||||
|
|
||||||
if n >= threshold {
|
if n >= threshold {
|
||||||
candidate := candidates[index%len(candidates)]
|
candidate := candidates[index%len(candidates)]
|
||||||
|
@ -178,12 +185,11 @@ func Name() string {
|
||||||
return name
|
return name
|
||||||
}
|
}
|
||||||
|
|
||||||
func vote(ctx storage.Context, id, from []byte) int {
|
func vote(ctx storage.Context, epoch int, id, from []byte) int {
|
||||||
var (
|
var (
|
||||||
newCandidates []ballot
|
newCandidates []ballot
|
||||||
candidates = getBallots(ctx)
|
candidates = getBallots(ctx)
|
||||||
found = -1
|
found = -1
|
||||||
blockHeight = blockchain.GetHeight()
|
|
||||||
)
|
)
|
||||||
|
|
||||||
for i := 0; i < len(candidates); i++ {
|
for i := 0; i < len(candidates); i++ {
|
||||||
|
@ -198,12 +204,12 @@ func vote(ctx storage.Context, id, from []byte) int {
|
||||||
}
|
}
|
||||||
|
|
||||||
voters = append(voters, from)
|
voters = append(voters, from)
|
||||||
cnd = ballot{id: id, n: voters, block: blockHeight}
|
cnd = ballot{id: id, n: voters, height: epoch}
|
||||||
found = len(voters)
|
found = len(voters)
|
||||||
}
|
}
|
||||||
|
|
||||||
// do not add old ballots, they are invalid
|
// add only valid ballots with current epochs
|
||||||
if blockHeight-cnd.block <= blockDiff {
|
if cnd.height == epoch {
|
||||||
newCandidates = append(newCandidates, cnd)
|
newCandidates = append(newCandidates, cnd)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -211,9 +217,9 @@ func vote(ctx storage.Context, id, from []byte) int {
|
||||||
if found < 0 {
|
if found < 0 {
|
||||||
voters := [][]byte{from}
|
voters := [][]byte{from}
|
||||||
newCandidates = append(newCandidates, ballot{
|
newCandidates = append(newCandidates, ballot{
|
||||||
id: id,
|
id: id,
|
||||||
n: voters,
|
n: voters,
|
||||||
block: blockHeight})
|
height: epoch})
|
||||||
found = 1
|
found = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -259,7 +265,7 @@ func bytesEqual(a []byte, b []byte) bool {
|
||||||
|
|
||||||
func voteID(epoch interface{}, args [][]byte) []byte {
|
func voteID(epoch interface{}, args [][]byte) []byte {
|
||||||
var (
|
var (
|
||||||
result []byte
|
result []byte
|
||||||
epochBytes = epoch.([]byte)
|
epochBytes = epoch.([]byte)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,6 @@ package alphabetcontract
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/nspcc-dev/neo-go/pkg/interop/binary"
|
"github.com/nspcc-dev/neo-go/pkg/interop/binary"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/interop/blockchain"
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/interop/contract"
|
"github.com/nspcc-dev/neo-go/pkg/interop/contract"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/interop/crypto"
|
"github.com/nspcc-dev/neo-go/pkg/interop/crypto"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/interop/engine"
|
"github.com/nspcc-dev/neo-go/pkg/interop/engine"
|
||||||
|
@ -17,9 +16,9 @@ type (
|
||||||
}
|
}
|
||||||
|
|
||||||
ballot struct {
|
ballot struct {
|
||||||
id []byte // id of the voting decision
|
id []byte // hash of validators list
|
||||||
n [][]byte // already voted inner ring nodes
|
n [][]byte // already voted inner ring nodes
|
||||||
block int // block with the last vote
|
height int // height is an neofs epoch when ballot was registered
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -35,9 +34,7 @@ const (
|
||||||
|
|
||||||
netmapContractKey = "netmapScriptHash"
|
netmapContractKey = "netmapScriptHash"
|
||||||
|
|
||||||
blockDiff = 20 // amount of blocks when ballot get discarded
|
threshold = totalAlphabetContracts * 2 / 3 + 1
|
||||||
|
|
||||||
threshold = totalAlphabetContracts*2/3 + 1
|
|
||||||
voteKey = "ballots"
|
voteKey = "ballots"
|
||||||
|
|
||||||
totalAlphabetContracts = 7
|
totalAlphabetContracts = 7
|
||||||
|
@ -91,6 +88,11 @@ func irList() []irNode {
|
||||||
return engine.AppCall(netmapContractAddr, "innerRingList").([]irNode)
|
return engine.AppCall(netmapContractAddr, "innerRingList").([]irNode)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func currentEpoch() int {
|
||||||
|
netmapContractAddr := storage.Get(ctx, netmapContractKey).([]byte)
|
||||||
|
return engine.AppCall(netmapContractAddr, "epoch").(int)
|
||||||
|
}
|
||||||
|
|
||||||
func checkPermission(ir []irNode) bool {
|
func checkPermission(ir []irNode) bool {
|
||||||
if len(ir) <= index {
|
if len(ir) <= index {
|
||||||
return false
|
return false
|
||||||
|
@ -153,8 +155,13 @@ func Vote(epoch int, candidates [][]byte) {
|
||||||
panic("invalid invoker")
|
panic("invalid invoker")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
curEpoch := currentEpoch()
|
||||||
|
if epoch != curEpoch {
|
||||||
|
panic("invalid epoch")
|
||||||
|
}
|
||||||
|
|
||||||
id := voteID(epoch, candidates)
|
id := voteID(epoch, candidates)
|
||||||
n := vote(ctx, id, key)
|
n := vote(ctx, curEpoch, id, key)
|
||||||
|
|
||||||
if n >= threshold {
|
if n >= threshold {
|
||||||
candidate := candidates[index%len(candidates)]
|
candidate := candidates[index%len(candidates)]
|
||||||
|
@ -178,12 +185,11 @@ func Name() string {
|
||||||
return name
|
return name
|
||||||
}
|
}
|
||||||
|
|
||||||
func vote(ctx storage.Context, id, from []byte) int {
|
func vote(ctx storage.Context, epoch int, id, from []byte) int {
|
||||||
var (
|
var (
|
||||||
newCandidates []ballot
|
newCandidates []ballot
|
||||||
candidates = getBallots(ctx)
|
candidates = getBallots(ctx)
|
||||||
found = -1
|
found = -1
|
||||||
blockHeight = blockchain.GetHeight()
|
|
||||||
)
|
)
|
||||||
|
|
||||||
for i := 0; i < len(candidates); i++ {
|
for i := 0; i < len(candidates); i++ {
|
||||||
|
@ -198,12 +204,12 @@ func vote(ctx storage.Context, id, from []byte) int {
|
||||||
}
|
}
|
||||||
|
|
||||||
voters = append(voters, from)
|
voters = append(voters, from)
|
||||||
cnd = ballot{id: id, n: voters, block: blockHeight}
|
cnd = ballot{id: id, n: voters, height: epoch}
|
||||||
found = len(voters)
|
found = len(voters)
|
||||||
}
|
}
|
||||||
|
|
||||||
// do not add old ballots, they are invalid
|
// add only valid ballots with current epochs
|
||||||
if blockHeight-cnd.block <= blockDiff {
|
if cnd.height == epoch {
|
||||||
newCandidates = append(newCandidates, cnd)
|
newCandidates = append(newCandidates, cnd)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -211,9 +217,9 @@ func vote(ctx storage.Context, id, from []byte) int {
|
||||||
if found < 0 {
|
if found < 0 {
|
||||||
voters := [][]byte{from}
|
voters := [][]byte{from}
|
||||||
newCandidates = append(newCandidates, ballot{
|
newCandidates = append(newCandidates, ballot{
|
||||||
id: id,
|
id: id,
|
||||||
n: voters,
|
n: voters,
|
||||||
block: blockHeight})
|
height: epoch})
|
||||||
found = 1
|
found = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -259,7 +265,7 @@ func bytesEqual(a []byte, b []byte) bool {
|
||||||
|
|
||||||
func voteID(epoch interface{}, args [][]byte) []byte {
|
func voteID(epoch interface{}, args [][]byte) []byte {
|
||||||
var (
|
var (
|
||||||
result []byte
|
result []byte
|
||||||
epochBytes = epoch.([]byte)
|
epochBytes = epoch.([]byte)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,6 @@ package alphabetcontract
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/nspcc-dev/neo-go/pkg/interop/binary"
|
"github.com/nspcc-dev/neo-go/pkg/interop/binary"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/interop/blockchain"
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/interop/contract"
|
"github.com/nspcc-dev/neo-go/pkg/interop/contract"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/interop/crypto"
|
"github.com/nspcc-dev/neo-go/pkg/interop/crypto"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/interop/engine"
|
"github.com/nspcc-dev/neo-go/pkg/interop/engine"
|
||||||
|
@ -17,9 +16,9 @@ type (
|
||||||
}
|
}
|
||||||
|
|
||||||
ballot struct {
|
ballot struct {
|
||||||
id []byte // id of the voting decision
|
id []byte // hash of validators list
|
||||||
n [][]byte // already voted inner ring nodes
|
n [][]byte // already voted inner ring nodes
|
||||||
block int // block with the last vote
|
height int // height is an neofs epoch when ballot was registered
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -35,9 +34,7 @@ const (
|
||||||
|
|
||||||
netmapContractKey = "netmapScriptHash"
|
netmapContractKey = "netmapScriptHash"
|
||||||
|
|
||||||
blockDiff = 20 // amount of blocks when ballot get discarded
|
threshold = totalAlphabetContracts * 2 / 3 + 1
|
||||||
|
|
||||||
threshold = totalAlphabetContracts*2/3 + 1
|
|
||||||
voteKey = "ballots"
|
voteKey = "ballots"
|
||||||
|
|
||||||
totalAlphabetContracts = 7
|
totalAlphabetContracts = 7
|
||||||
|
@ -91,6 +88,11 @@ func irList() []irNode {
|
||||||
return engine.AppCall(netmapContractAddr, "innerRingList").([]irNode)
|
return engine.AppCall(netmapContractAddr, "innerRingList").([]irNode)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func currentEpoch() int {
|
||||||
|
netmapContractAddr := storage.Get(ctx, netmapContractKey).([]byte)
|
||||||
|
return engine.AppCall(netmapContractAddr, "epoch").(int)
|
||||||
|
}
|
||||||
|
|
||||||
func checkPermission(ir []irNode) bool {
|
func checkPermission(ir []irNode) bool {
|
||||||
if len(ir) <= index {
|
if len(ir) <= index {
|
||||||
return false
|
return false
|
||||||
|
@ -153,8 +155,13 @@ func Vote(epoch int, candidates [][]byte) {
|
||||||
panic("invalid invoker")
|
panic("invalid invoker")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
curEpoch := currentEpoch()
|
||||||
|
if epoch != curEpoch {
|
||||||
|
panic("invalid epoch")
|
||||||
|
}
|
||||||
|
|
||||||
id := voteID(epoch, candidates)
|
id := voteID(epoch, candidates)
|
||||||
n := vote(ctx, id, key)
|
n := vote(ctx, curEpoch, id, key)
|
||||||
|
|
||||||
if n >= threshold {
|
if n >= threshold {
|
||||||
candidate := candidates[index%len(candidates)]
|
candidate := candidates[index%len(candidates)]
|
||||||
|
@ -178,12 +185,11 @@ func Name() string {
|
||||||
return name
|
return name
|
||||||
}
|
}
|
||||||
|
|
||||||
func vote(ctx storage.Context, id, from []byte) int {
|
func vote(ctx storage.Context, epoch int, id, from []byte) int {
|
||||||
var (
|
var (
|
||||||
newCandidates []ballot
|
newCandidates []ballot
|
||||||
candidates = getBallots(ctx)
|
candidates = getBallots(ctx)
|
||||||
found = -1
|
found = -1
|
||||||
blockHeight = blockchain.GetHeight()
|
|
||||||
)
|
)
|
||||||
|
|
||||||
for i := 0; i < len(candidates); i++ {
|
for i := 0; i < len(candidates); i++ {
|
||||||
|
@ -198,12 +204,12 @@ func vote(ctx storage.Context, id, from []byte) int {
|
||||||
}
|
}
|
||||||
|
|
||||||
voters = append(voters, from)
|
voters = append(voters, from)
|
||||||
cnd = ballot{id: id, n: voters, block: blockHeight}
|
cnd = ballot{id: id, n: voters, height: epoch}
|
||||||
found = len(voters)
|
found = len(voters)
|
||||||
}
|
}
|
||||||
|
|
||||||
// do not add old ballots, they are invalid
|
// add only valid ballots with current epochs
|
||||||
if blockHeight-cnd.block <= blockDiff {
|
if cnd.height == epoch {
|
||||||
newCandidates = append(newCandidates, cnd)
|
newCandidates = append(newCandidates, cnd)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -211,9 +217,9 @@ func vote(ctx storage.Context, id, from []byte) int {
|
||||||
if found < 0 {
|
if found < 0 {
|
||||||
voters := [][]byte{from}
|
voters := [][]byte{from}
|
||||||
newCandidates = append(newCandidates, ballot{
|
newCandidates = append(newCandidates, ballot{
|
||||||
id: id,
|
id: id,
|
||||||
n: voters,
|
n: voters,
|
||||||
block: blockHeight})
|
height: epoch})
|
||||||
found = 1
|
found = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -259,7 +265,7 @@ func bytesEqual(a []byte, b []byte) bool {
|
||||||
|
|
||||||
func voteID(epoch interface{}, args [][]byte) []byte {
|
func voteID(epoch interface{}, args [][]byte) []byte {
|
||||||
var (
|
var (
|
||||||
result []byte
|
result []byte
|
||||||
epochBytes = epoch.([]byte)
|
epochBytes = epoch.([]byte)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,6 @@ package alphabetcontract
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/nspcc-dev/neo-go/pkg/interop/binary"
|
"github.com/nspcc-dev/neo-go/pkg/interop/binary"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/interop/blockchain"
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/interop/contract"
|
"github.com/nspcc-dev/neo-go/pkg/interop/contract"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/interop/crypto"
|
"github.com/nspcc-dev/neo-go/pkg/interop/crypto"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/interop/engine"
|
"github.com/nspcc-dev/neo-go/pkg/interop/engine"
|
||||||
|
@ -17,9 +16,9 @@ type (
|
||||||
}
|
}
|
||||||
|
|
||||||
ballot struct {
|
ballot struct {
|
||||||
id []byte // id of the voting decision
|
id []byte // hash of validators list
|
||||||
n [][]byte // already voted inner ring nodes
|
n [][]byte // already voted inner ring nodes
|
||||||
block int // block with the last vote
|
height int // height is an neofs epoch when ballot was registered
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -35,9 +34,7 @@ const (
|
||||||
|
|
||||||
netmapContractKey = "netmapScriptHash"
|
netmapContractKey = "netmapScriptHash"
|
||||||
|
|
||||||
blockDiff = 20 // amount of blocks when ballot get discarded
|
threshold = totalAlphabetContracts * 2 / 3 + 1
|
||||||
|
|
||||||
threshold = totalAlphabetContracts*2/3 + 1
|
|
||||||
voteKey = "ballots"
|
voteKey = "ballots"
|
||||||
|
|
||||||
totalAlphabetContracts = 7
|
totalAlphabetContracts = 7
|
||||||
|
@ -91,6 +88,11 @@ func irList() []irNode {
|
||||||
return engine.AppCall(netmapContractAddr, "innerRingList").([]irNode)
|
return engine.AppCall(netmapContractAddr, "innerRingList").([]irNode)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func currentEpoch() int {
|
||||||
|
netmapContractAddr := storage.Get(ctx, netmapContractKey).([]byte)
|
||||||
|
return engine.AppCall(netmapContractAddr, "epoch").(int)
|
||||||
|
}
|
||||||
|
|
||||||
func checkPermission(ir []irNode) bool {
|
func checkPermission(ir []irNode) bool {
|
||||||
if len(ir) <= index {
|
if len(ir) <= index {
|
||||||
return false
|
return false
|
||||||
|
@ -153,8 +155,13 @@ func Vote(epoch int, candidates [][]byte) {
|
||||||
panic("invalid invoker")
|
panic("invalid invoker")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
curEpoch := currentEpoch()
|
||||||
|
if epoch != curEpoch {
|
||||||
|
panic("invalid epoch")
|
||||||
|
}
|
||||||
|
|
||||||
id := voteID(epoch, candidates)
|
id := voteID(epoch, candidates)
|
||||||
n := vote(ctx, id, key)
|
n := vote(ctx, curEpoch, id, key)
|
||||||
|
|
||||||
if n >= threshold {
|
if n >= threshold {
|
||||||
candidate := candidates[index%len(candidates)]
|
candidate := candidates[index%len(candidates)]
|
||||||
|
@ -178,12 +185,11 @@ func Name() string {
|
||||||
return name
|
return name
|
||||||
}
|
}
|
||||||
|
|
||||||
func vote(ctx storage.Context, id, from []byte) int {
|
func vote(ctx storage.Context, epoch int, id, from []byte) int {
|
||||||
var (
|
var (
|
||||||
newCandidates []ballot
|
newCandidates []ballot
|
||||||
candidates = getBallots(ctx)
|
candidates = getBallots(ctx)
|
||||||
found = -1
|
found = -1
|
||||||
blockHeight = blockchain.GetHeight()
|
|
||||||
)
|
)
|
||||||
|
|
||||||
for i := 0; i < len(candidates); i++ {
|
for i := 0; i < len(candidates); i++ {
|
||||||
|
@ -198,12 +204,12 @@ func vote(ctx storage.Context, id, from []byte) int {
|
||||||
}
|
}
|
||||||
|
|
||||||
voters = append(voters, from)
|
voters = append(voters, from)
|
||||||
cnd = ballot{id: id, n: voters, block: blockHeight}
|
cnd = ballot{id: id, n: voters, height: epoch}
|
||||||
found = len(voters)
|
found = len(voters)
|
||||||
}
|
}
|
||||||
|
|
||||||
// do not add old ballots, they are invalid
|
// add only valid ballots with current epochs
|
||||||
if blockHeight-cnd.block <= blockDiff {
|
if cnd.height == epoch {
|
||||||
newCandidates = append(newCandidates, cnd)
|
newCandidates = append(newCandidates, cnd)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -211,9 +217,9 @@ func vote(ctx storage.Context, id, from []byte) int {
|
||||||
if found < 0 {
|
if found < 0 {
|
||||||
voters := [][]byte{from}
|
voters := [][]byte{from}
|
||||||
newCandidates = append(newCandidates, ballot{
|
newCandidates = append(newCandidates, ballot{
|
||||||
id: id,
|
id: id,
|
||||||
n: voters,
|
n: voters,
|
||||||
block: blockHeight})
|
height: epoch})
|
||||||
found = 1
|
found = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -259,7 +265,7 @@ func bytesEqual(a []byte, b []byte) bool {
|
||||||
|
|
||||||
func voteID(epoch interface{}, args [][]byte) []byte {
|
func voteID(epoch interface{}, args [][]byte) []byte {
|
||||||
var (
|
var (
|
||||||
result []byte
|
result []byte
|
||||||
epochBytes = epoch.([]byte)
|
epochBytes = epoch.([]byte)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue