Commit d496c485 authored by Son of Odin's avatar Son of Odin 💬

Merge branch '376-issue' into 'master'

Resolve "[ADD] Update HasMajority for tss blame"

Closes #376

See merge request !693
parents 42ec34ad a6710e9d
Pipeline #130164104 passed with stages
in 30 minutes and 2 seconds
......@@ -81,7 +81,7 @@ var (
NewPoolStaker = types.NewPoolStaker
NewStakerPool = types.NewStakerPool
NewMsgEndPool = types.NewMsgEndPool
HasMajority = types.HasMajority
HasSuperMajority = types.HasSuperMajority
ChooseSignerParty = types.ChooseSignerParty
GetThreshold = types.GetThreshold
ModuleCdc = types.ModuleCdc
......
......@@ -5,9 +5,10 @@ import (
sdk "github.com/cosmos/cosmos-sdk/types"
. "gopkg.in/check.v1"
tssCommon "gitlab.com/thorchain/tss/go-tss/common"
"gitlab.com/thorchain/thornode/common"
"gitlab.com/thorchain/thornode/constants"
tssCommon "gitlab.com/thorchain/tss/go-tss/common"
)
type HandlerTssKeysignFailSuite struct{}
......@@ -229,6 +230,44 @@ func (h HandlerTssKeysignFailSuite) TestTssKeysignFailHandler(c *C) {
},
expectedResult: sdk.CodeInternal,
},
{
name: "without majority it should not take any actions",
messageCreator: func(helper tssKeysignFailHandlerTestHelper) sdk.Msg {
return NewMsgTssKeysignFail(helper.ctx.BlockHeight(), helper.blame, "hello", common.Coins{common.NewCoin(common.BNBAsset, sdk.NewUint(100))}, helper.nodeAccount.NodeAddress)
},
runner: func(handler TssKeysignFailHandler, msg sdk.Msg, helper tssKeysignFailHandlerTestHelper) sdk.Result {
for i := 0; i < 3; i++ {
na := GetRandomNodeAccount(NodeActive)
if err := helper.keeper.SetNodeAccount(helper.ctx, na); err != nil {
return sdk.ErrInternal("fail to set node account").Result()
}
}
return handler.Run(helper.ctx, msg, semver.MustParse("0.1.0"), helper.constAccessor)
},
expectedResult: sdk.CodeOK,
},
{
name: "with majority it should take actions",
messageCreator: func(helper tssKeysignFailHandlerTestHelper) sdk.Msg {
return NewMsgTssKeysignFail(helper.ctx.BlockHeight(), helper.blame, "hello", common.Coins{common.NewCoin(common.BNBAsset, sdk.NewUint(100))}, helper.nodeAccount.NodeAddress)
},
runner: func(handler TssKeysignFailHandler, msg sdk.Msg, helper tssKeysignFailHandlerTestHelper) sdk.Result {
var na NodeAccount
for i := 0; i < 3; i++ {
na = GetRandomNodeAccount(NodeActive)
if err := helper.keeper.SetNodeAccount(helper.ctx, na); err != nil {
return sdk.ErrInternal("fail to set node account").Result()
}
}
result := handler.Run(helper.ctx, msg, semver.MustParse("0.1.0"), helper.constAccessor)
if result.Code != sdk.CodeOK {
return result
}
msg = NewMsgTssKeysignFail(helper.ctx.BlockHeight(), helper.blame, "hello", common.Coins{common.NewCoin(common.BNBAsset, sdk.NewUint(100))}, na.NodeAddress)
return handler.Run(helper.ctx, msg, semver.MustParse("0.1.0"), helper.constAccessor)
},
expectedResult: sdk.CodeOK,
},
}
for _, tc := range testCases {
helper := newTssKeysignFailHandlerTestHelper(c)
......
......@@ -108,7 +108,7 @@ func (k KVStore) GetMinJoinVersion(ctx sdk.Context) semver.Version {
for _, info := range vCount {
// skip those version that doesn't have majority
if !HasMajority(info.count, totalCount) {
if !HasSuperMajority(info.count, totalCount) {
continue
}
if info.version.GT(version) {
......
......@@ -15,5 +15,4 @@ var _ = Suite(&QuerySuite{})
func (s QuerySuite) TestQuery(c *C) {
c.Check(QueryTxIn.Endpoint("foo", "bar"), Equals, "/foo/tx/{bar}")
c.Check(QueryTxIn.Path("foo", "bar"), Equals, "custom/foo/txin/bar")
}
......@@ -221,7 +221,7 @@ func (tx ObservedTxVoter) HasConsensus(nodeAccounts NodeAccounts) bool {
count += 1
}
}
if HasMajority(count, len(nodeAccounts)) {
if HasSuperMajority(count, len(nodeAccounts)) {
return true
}
}
......@@ -237,7 +237,7 @@ func (tx ObservedTxVoter) GetTx(nodeAccounts NodeAccounts) ObservedTx {
count += 1
}
}
if HasMajority(count, len(nodeAccounts)) {
if HasSuperMajority(count, len(nodeAccounts)) {
return txIn
}
}
......
......@@ -13,19 +13,20 @@ import (
)
const (
DefaultCodespace sdk.CodespaceType = ModuleName
MajorityFactor uint64 = 3
DefaultCodespace sdk.CodespaceType = ModuleName
SuperMajorityFactor uint64 = 3
MajorityFactor uint64 = 2
)
// HasMajority return true when it has 2/3 majority
func HasMajority(signers, total int) bool {
// HasSuperMajority return true when it has 2/3 majority
func HasSuperMajority(signers, total int) bool {
if signers > total {
return false // will not have majority if THORNode have more signers than node accounts. This shouldn't be possible
}
if signers <= 0 {
return false // edge case
}
mU := sdk.NewUint(MajorityFactor)
mU := sdk.NewUint(SuperMajorityFactor)
// 10*4 / (6.67*2) <= 3
// 4*4 / (3*2) <= 3
......@@ -37,6 +38,23 @@ func HasMajority(signers, total int) bool {
return mU.GTE(factor)
}
// HasMajority return true when it has more than 1/2
func HasMajority(signers, total int) bool {
if signers > total {
return false // will not have majority if THORNode have more signers than node accounts. This shouldn't be possible
}
if signers <= 0 {
return false // edge case
}
mU := sdk.NewUint(MajorityFactor)
// Is able to determine "majority" without needing floats or DECs
tU := sdk.NewUint(uint64(total))
sU := sdk.NewUint(uint64(signers))
factor := tU.Quo(sU)
return mU.GTE(factor)
}
// GetThreshold calculate threshold
func GetThreshold(value int) (int, error) {
if value < 0 {
......
......@@ -15,21 +15,30 @@ type TypesSuite struct{}
var _ = Suite(&TypesSuite{})
func (s TypesSuite) TestHasMajority(c *C) {
func (s TypesSuite) TestHasSuperMajority(c *C) {
// happy path
c.Check(HasMajority(3, 4), Equals, true)
c.Check(HasMajority(2, 3), Equals, true)
c.Check(HasMajority(4, 4), Equals, true)
c.Check(HasMajority(1, 1), Equals, true)
c.Check(HasMajority(67, 100), Equals, true)
c.Check(HasSuperMajority(3, 4), Equals, true)
c.Check(HasSuperMajority(2, 3), Equals, true)
c.Check(HasSuperMajority(4, 4), Equals, true)
c.Check(HasSuperMajority(1, 1), Equals, true)
c.Check(HasSuperMajority(67, 100), Equals, true)
// unhappy path
c.Check(HasMajority(2, 4), Equals, false)
c.Check(HasMajority(9, 4), Equals, false)
c.Check(HasMajority(-9, 4), Equals, false)
c.Check(HasMajority(9, -4), Equals, false)
c.Check(HasMajority(0, 0), Equals, false)
c.Check(HasMajority(3, 0), Equals, false)
c.Check(HasSuperMajority(2, 4), Equals, false)
c.Check(HasSuperMajority(9, 4), Equals, false)
c.Check(HasSuperMajority(-9, 4), Equals, false)
c.Check(HasSuperMajority(9, -4), Equals, false)
c.Check(HasSuperMajority(0, 0), Equals, false)
c.Check(HasSuperMajority(3, 0), Equals, false)
}
func (TypesSuite) TestHasMajority(c *C) {
c.Check(HasMajority(3, 4), Equals, true)
c.Check(HasMajority(2, 3), Equals, true)
c.Check(HasMajority(1, 2), Equals, true)
c.Check(HasMajority(1, 3), Equals, false)
c.Check(HasMajority(2, 4), Equals, true)
c.Check(HasMajority(100000, 3000000), Equals, false)
}
func (TypesSuite) TestGetThreshold(c *C) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment