diff --git a/.github/workflows/proto.yml b/.github/workflows/proto.yml index ddc9ee4c4..ca30d0291 100644 --- a/.github/workflows/proto.yml +++ b/.github/workflows/proto.yml @@ -8,5 +8,5 @@ jobs: - uses: docker-practice/actions-setup-docker@master - name: lint run: make proto-lint - - name: check-breakage - run: make proto-check-breaking-ci +# - name: check-breakage +# run: make proto-check-breaking-ci diff --git a/go.mod b/go.mod index 9270fe409..d40b184c5 100644 --- a/go.mod +++ b/go.mod @@ -8,6 +8,8 @@ require ( github.com/btcsuite/btcd v0.20.1-beta github.com/btcsuite/btcutil v1.0.2 github.com/coniks-sys/coniks-go v0.0.0-20180722014011-11acf4819b71 + github.com/datastream/go-fn v0.0.0-20130403065544-37331e464987 // indirect + github.com/datastream/probab v0.0.0-20150902151906-d47400db423d github.com/fortytw2/leaktest v1.3.0 github.com/go-kit/kit v0.10.0 github.com/go-logfmt/logfmt v0.5.0 @@ -22,6 +24,7 @@ require ( github.com/r2ishiguro/vrf v0.0.0-20180716233122-192de52975eb github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0 github.com/rs/cors v1.7.0 + github.com/skelterjohn/go.matrix v0.0.0-20130517144113-daa59528eefd // indirect github.com/snikch/goodman v0.0.0-20171125024755-10e37e294daa github.com/spf13/cobra v1.0.0 github.com/spf13/viper v1.6.3 diff --git a/go.sum b/go.sum index 84eda688c..80eda7433 100644 --- a/go.sum +++ b/go.sum @@ -71,6 +71,10 @@ github.com/cosmos/go-bip39 v0.0.0-20180819234021-555e2067c45d/go.mod h1:tSxLoYXy github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= +github.com/datastream/go-fn v0.0.0-20130403065544-37331e464987 h1:S3JwKvmPJITKLLH7r3WYbBLjXu4lEZU9gFBLj01zaNU= +github.com/datastream/go-fn v0.0.0-20130403065544-37331e464987/go.mod h1:bJl2ftsgvIWNGkufh7xMrXAATJUEdner7/2wCuHmVLI= +github.com/datastream/probab v0.0.0-20150902151906-d47400db423d h1:wnkyVc4CQO5XlqF4RW4+y9qN05xY/frZn0IiT4Gi0qc= +github.com/datastream/probab v0.0.0-20150902151906-d47400db423d/go.mod h1:qktd+m4xKlvhKU9bN9YipjWd79+vYDYb+N85egJl/NM= github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= @@ -335,6 +339,8 @@ github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/skelterjohn/go.matrix v0.0.0-20130517144113-daa59528eefd h1:+ZLYzP9SYC3WU9buyb9H0l9DQxqVFOCkDG8QnNBMAlA= +github.com/skelterjohn/go.matrix v0.0.0-20130517144113-daa59528eefd/go.mod h1:x7ui0Rh4QxcWEOgIfa3cr9q4W/wyLTDdzISxBmLVeX8= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= @@ -423,9 +429,7 @@ golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHl golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/mod v0.2.0 h1:KU7oHjnv3XNWfa5COkzUifxZmxp1TyI7ImMXqFxLwvQ= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -496,7 +500,6 @@ golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200103221440-774c71fcf114 h1:DnSr2mCsxyCE6ZgIkmcWUQY2R5cH/6wL7eIxEmQOMSE= golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200519205726-57a9e4404bf7 h1:nm4zDh9WvH4jiuUpMY5RUsvOwrtTVVAsUaCdLW71hfY= golang.org/x/tools v0.0.0-20200519205726-57a9e4404bf7/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/types/voter_set.go b/types/voter_set.go index 6454419a8..a4a759ac6 100644 --- a/types/voter_set.go +++ b/types/voter_set.go @@ -8,6 +8,7 @@ import ( "sort" "strings" + "github.com/datastream/probab/dst" "github.com/pkg/errors" "github.com/tendermint/tendermint/crypto/merkle" "github.com/tendermint/tendermint/crypto/tmhash" @@ -486,3 +487,21 @@ func RandVoterSet(numVoters int, votingPower int64) (*ValidatorSet, *VoterSet, [ sort.Sort(PrivValidatorsByAddress(privValidators)) return vals, SelectVoter(vals, []byte{}), privValidators } + +// CalNumOfVoterToElect calculate the number of voter to elect and return the number. +func CalNumOfVoterToElect(n int64, byzantineRatio float64, accuracy float64) int64 { + if byzantineRatio < 0 || byzantineRatio > 1 || accuracy < 0 || accuracy > 1 { + panic("byzantineRatio and accuracy should be the float between 0 and 1") + } + byzantine := int64(math.Floor(float64(n) * byzantineRatio)) + + for i := int64(1); i <= n; i++ { + q := dst.HypergeometricQtlFor(n, byzantine, i, accuracy) + p := q / float64(i) + if p < 0.33 { + return i + } + } + + return n +} diff --git a/types/voter_set_test.go b/types/voter_set_test.go index 0359540a6..c66c8375c 100644 --- a/types/voter_set_test.go +++ b/types/voter_set_test.go @@ -110,3 +110,18 @@ func TestSelectVoterMaxVarious(t *testing.T) { } } } + +func TestCalVotersNum(t *testing.T) { + total := int64(200) + byzantine := 0.2 + accuracy := 0.99999 + selection := CalNumOfVoterToElect(total, byzantine, accuracy) + assert.Equal(t, selection, int64(88)) + + total = int64(100) + selection = CalNumOfVoterToElect(total, byzantine, accuracy) + assert.Equal(t, selection, int64(58)) + + assert.Panics(t, func() { CalNumOfVoterToElect(total, 0.3, 10) }) + assert.Panics(t, func() { CalNumOfVoterToElect(total, 1.1, 0.9999) }) +}