Fixed randomize generator not using matrix mechanism.

This commit is contained in:
MestryOmkar 2018-11-05 11:58:04 +05:30
parent 20c5123739
commit 7aa35671ad
4 changed files with 56 additions and 140 deletions

View file

@ -105,29 +105,21 @@ func TestSendTxRandomizeSecretAndOpening(t *testing.T) {
backend.Commit()
// Get randomize secret from SC.
secretsArr, err := randomizeContract.GetSecret(acc1Addr)
if err != nil {
t.Fatalf("Can't get secret from SC: %v", err)
}
if len(secretsArr) <= 0 {
t.Error("Empty get secrets from SC", err)
}
// Decrypt randomize from SC.
secrets, err := randomizeContract.GetSecret(acc1Addr)
if err != nil {
t.Error("Fail get secrets from randomize", err)
}
if len(secrets) <= 0 {
t.Error("Empty get secrets from SC", err)
}
// Decrypt randomize from SC.
opening, err := randomizeContract.GetOpening(acc1Addr)
if err != nil {
t.Fatalf("Can't get secret from SC: %v", err)
}
randomizes, err := contracts.DecryptRandomizeFromSecretsAndOpening(secrets, opening)
t.Log("randomizes", randomizes)
randomize, err := contracts.DecryptRandomizeFromSecretsAndOpening(secrets, opening)
t.Log("randomize", randomize)
if err != nil {
t.Error("Can't decrypt secret and opening", err)
}
if len(randomizes) != 901 {
t.Error("Randomize length not match", "length", len(randomizes))
}
}

View file

@ -24,7 +24,6 @@ import (
"github.com/ethereum/go-ethereum/params"
"github.com/pkg/errors"
"io"
"math"
"math/big"
"math/rand"
"strconv"
@ -38,9 +37,10 @@ const (
RewardFoundationPercent = 10
HexSetSecret = "34d38600"
HexSetOpening = "e11f5ba2"
EpocBlockSecret = 950
EpocBlockOpening = 980
EpocBlockRandomize = 900
EpocBlockSecret = 20
EpocBlockOpening = 30
EpocBlockRandomize = 50
MaxMasternodes = 150
M2ByteLength = 4
extraVanity = 32 // Fixed number of extra-data prefix bytes reserved for signer vanity
extraSeal = 65 // Fixed number of extra-data suffix bytes reserved for signer seal
@ -153,16 +153,13 @@ func CreateTxSign(blockNumber *big.Int, blockHash common.Hash, nonce uint64, blo
// Send secret key into randomize smartcontract.
func BuildTxSecretRandomize(nonce uint64, randomizeAddr common.Address, epocNumber uint64, randomizeKey []byte) (*types.Transaction, error) {
data := common.Hex2Bytes(HexSetSecret)
secretMax := math.Round(float64(epocNumber / 10))
secrets := Shuffle(NewSlice(0, int64(secretMax), 1))
rand.Seed(time.Now().UnixNano())
secretNumb := rand.Intn(int(epocNumber))
// Append randomize suffix in -1, 0, 1.
arrSuffix := []int64{-1, 1}
rand.Seed(time.Now().UnixNano())
randIndex := rand.Intn(len(arrSuffix))
secrets = append(secrets, arrSuffix[randIndex])
secrets := []int64{int64(secretNumb)}
sizeOfArray := int64(32)
// Build extra data for tx with first position is size of array byte and second position are length of array byte.
arrSizeOfSecrets := common.LeftPadBytes(new(big.Int).SetInt64(sizeOfArray).Bytes(), 32)
arrLengthOfSecrets := common.LeftPadBytes(new(big.Int).SetInt64(int64(len(secrets))).Bytes(), 32)
@ -204,7 +201,7 @@ func GetSignersFromContract(addrBlockSigner common.Address, client bind.Contract
}
// Get random from randomize contract.
func GetRandomizeFromContract(client bind.ContractBackend, addrMasternode common.Address) ([]int64, error) {
func GetRandomizeFromContract(client bind.ContractBackend, addrMasternode common.Address) (int64, error) {
randomize, err := randomizeContract.NewXDCRandomize(common.HexToAddress(common.RandomizeSMC), client)
if err != nil {
log.Error("Fail to get instance of randomize", "error", err)
@ -223,26 +220,29 @@ func GetRandomizeFromContract(client bind.ContractBackend, addrMasternode common
}
// Generate m2 listing from randomize array.
func GenM2FromRandomize(randomizes [][]int64) ([]int64, error) {
// Separate array.
arrRandomizes := TransposeMatrix(randomizes)
lenRandomize := len(arrRandomizes)
arrayA := arrRandomizes[:lenRandomize-2]
arrayB := arrRandomizes[lenRandomize-1:]
matrixResult, err := DotMatrix(arrayA, arrayB)
if err != nil {
log.Error("Fail to dot matrix", "error", err)
return nil, err
func GenM2FromRandomize(randomizes []int64) ([]int64, error) {
blockValidator := NewSlice(int64(0), MaxMasternodes, 1)
randIndexs := make([]int64, MaxMasternodes)
total := int64(0)
var temp int64 = 0
for _, j := range randomizes {
total += j
}
lenMasternode := len(arrayB[0])
result := make([]int64, lenRandomize)
for i, v := range matrixResult {
result[i] = int64(math.Abs(float64(v))) % int64(lenMasternode)
rand.Seed(total)
for i := len(blockValidator) - 1; i >= 0; i-- {
blockLength := len(blockValidator) - 1
if blockLength <= 1 {
blockLength = 1
}
randomIndex := int64(rand.Intn(blockLength))
temp = blockValidator[randomIndex]
blockValidator[randomIndex] = blockValidator[i]
blockValidator[i] = temp
blockValidator = append(blockValidator[:i], blockValidator[i+1:]...)
randIndexs[i] = temp
}
return result, nil
return randIndexs, nil
}
// Get validators from m2 array integer.
@ -284,12 +284,10 @@ func DecodeValidatorsHexData(validatorsStr string) ([]int64, error) {
}
// Decrypt randomize from secrets and opening.
func DecryptRandomizeFromSecretsAndOpening(secrets [][32]byte, opening [32]byte) ([]int64, error) {
var random []int64
var completedRandomize []int64
random = make([]int64, len(secrets))
func DecryptRandomizeFromSecretsAndOpening(secrets [][32]byte, opening [32]byte) (int64, error) {
var random int64
if len(secrets) > 0 {
for i, secret := range secrets {
for _, secret := range secrets {
trimSecret := bytes.TrimLeft(secret[:], "\x00")
decryptSecret := Decrypt(opening[:], string(trimSecret))
if isInt(decryptSecret) {
@ -297,26 +295,12 @@ func DecryptRandomizeFromSecretsAndOpening(secrets [][32]byte, opening [32]byte)
if err != nil {
log.Error("Can not convert string to integer", "error", err)
}
random[i] = int64(intNumber)
random = int64(intNumber)
}
}
}
// Generate full randomize.
randomMax := len(random) - 1
if randomMax > 0 {
for i, randNumber := range random {
if i < randomMax {
for j := 0; j < 10; j++ {
completedRandomize = append(completedRandomize, randNumber*10+int64(j))
}
}
}
completedRandomize = append(completedRandomize, random[randomMax])
}
log.Error("random", "completedRandomize", completedRandomize, "randomMax", randomMax)
return completedRandomize, nil
return random, nil
}
// Calculate reward for reward checkpoint.
@ -568,33 +552,6 @@ func isInt(strNumber string) bool {
}
}
// Helper function for transpose matrix.
func TransposeMatrix(x [][]int64) [][]int64 {
out := make([][]int64, len(x[0]))
for i := 0; i < len(x); i += 1 {
for j := 0; j < len(x[0]); j += 1 {
out[j] = append(out[j], x[i][j])
}
}
return out
}
// Helper function for multiplication matrix.
func DotMatrix(x, y [][]int64) ([]int64, error) {
if len(x[0]) != len(y[0]) {
return nil, errors.New("Can't do matrix multiplication.")
}
out := make([]int64, len(x))
for i := 0; i < len(x); i += 1 {
for j := 0; j < len(y[0]); j += 1 {
out[i] += x[i][j] * y[0][j]
}
}
return out, nil
}
// Get masternodes address from checkpoint Header.
func GetMasternodesFromCheckpointHeader(checkpointHeader *types.Header) []common.Address {
masternodes := make([]common.Address, (len(checkpointHeader.Extra)-extraVanity-extraSeal)/common.AddressLength)

View file

@ -135,40 +135,6 @@ func TestEncryptDecrypt(t *testing.T) {
t.Log("Encrypt", encrypt, "Test", string(randomByte), "Decrypt", decrypt, "trim", string(bytes.TrimLeft([]byte(decrypt), "\x00")))
}
func TestTransposeMatrix(t *testing.T) {
a := [][]int64{
{0, 1, 2, 3, 4},
{4, 5, 6, 7, 8},
}
b := [][]int64{
{0, 4},
{1, 5},
{2, 6},
{3, 7},
{4, 8},
}
if !isArrayEqual(b, TransposeMatrix(a)) {
t.Errorf("Fail to transpose matrix %v - %v", a, TransposeMatrix(a))
}
}
func TestMultiMatrix(t *testing.T) {
a := make([][]int64, 6)
b := [][]int64{
{1, -1, -1, 1, 1, -1},
}
for i := 0; i < len(b[0]); i++ {
a[i] = Shuffle(NewSlice(0, 6, 1))
}
c, err := DotMatrix(a, b)
if err != nil {
t.Error("Fail to test dot matrix", err)
}
if len(a[0]) != len(c) {
t.Errorf("Fail to test dot matrix result %v - %v - %v", a, b, c)
}
}
func isArrayEqual(a [][]int64, b [][]int64) bool {
if len(a) != len(b) {
return false
@ -185,25 +151,28 @@ func isArrayEqual(a [][]int64, b [][]int64) bool {
// Unit test for
func TestGenM2FromRandomize(t *testing.T) {
a := [][]int64{
{37, 23, 17, 45, 38, 8, 21, 28, 15, 41, 1, 25, 4, 30, 31, 0, 9, 16, 46, 13, 36, 7, 19, 27, 47, 32, 22, 3, 20, 33, 2, 35, 49, 6, 42, 34, 44, 10, 29, 26, 12, 43, 48, 24, 40, 14, 18, 39, 5, 11, 1},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{28, 16, 13, 31, 32, 36, 44, 14, 37, 33, 3, 23, 17, 46, 35, 30, 45, 27, 9, 41, 7, 19, 10, 24, 5, 34, 29, 18, 21, 15, 0, 2, 25, 39, 11, 4, 22, 6, 48, 42, 12, 26, 1, 47, 43, 20, 40, 38, 8, 49, -1},
var a []int64
for i := 0; i <= 10; i++ {
rand.Seed(time.Now().UTC().UnixNano())
a = append(a, int64(rand.Intn(9999)))
}
b, err := GenM2FromRandomize(a)
t.Log("randomize", b)
t.Log("randomize", b, "len", len(b))
if err != nil {
t.Error("Fail to test gen m2 for randomize.", err)
}
c := []int64{0, 1, 1, 2, 0, 1, 2, 2, 1, 2, 2, 2, 1, 1, 1, 0, 0, 2, 1, 1, 2, 0, 0, 0, 0, 2, 1, 0, 1, 0, 2, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 2, 2, 2, 0, 0, 1, 1, 0, 0, 0}
if !isArrayEqual([][]int64{b}, [][]int64{c}) {
t.Errorf("Fail to get m2 result %v", b)
// Test Permutation Without Fixed-point.
M1List := NewSlice(int64(0), MaxMasternodes, 1)
for i, m1 := range M1List {
if m1 == b[i] {
t.Errorf("Error check Permutation Without Fixed-point %v - %v - %v", i, b[i], a)
}
}
}
// Unit test for validator m2.
func TestBuildValidatorFromM2(t *testing.T) {
a := []int64{0, 1, 1, 2, 0, 1, 2, 128, 150, 2, 2, 2, 1, 1, 1, 0, 0, 2, 1, 1, 2, 0, 0, 0, 0, 2, 1, 0, 1, 0, 2, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 2, 2, 2, 0, 0, 1, 1, 0, 0, 0}
a := []int64{84, 58, 27, 96, 127, 60, 136, 20, 121, 31, 87, 85, 40, 120, 149, 109, 141, 145, 11, 110, 147, 35, 76, 46, 34, 108, 72, 103, 102, 12, 23, 47, 70, 86, 125, 112, 128, 13, 130, 98, 126, 62, 132, 111, 134, 6, 106, 67, 24, 91, 101, 50, 94, 43, 77, 73, 129, 71, 51, 10, 92, 29, 80, 95, 33, 100, 124, 75, 38, 133, 79, 83, 61, 36, 122, 99, 16, 28, 18, 116, 140, 97, 119, 82, 148, 48, 56, 32, 93, 107, 69, 68, 123, 81, 22, 137, 25, 115, 44, 8, 42, 131, 143, 17, 55, 89, 9, 15, 19, 59, 146, 54, 5, 30, 41, 144, 117, 1, 104, 49, 105, 45, 88, 78, 74, 135, 0, 21, 57, 3, 66, 52, 63, 138, 4, 114, 37, 118, 14, 2, 26, 7, 65, 139, 39, 64, 90, 142, 53, 113}
b := BuildValidatorFromM2(a)
c := ExtractValidatorsFromBytes(b)
if !isArrayEqual([][]int64{a}, [][]int64{c}) {
@ -218,7 +187,8 @@ func TestDecodeValidatorsHexData(t *testing.T) {
if err != nil {
t.Error("Fail to decode validator from hex string", err)
}
c := []int64{1, 0, 2, 1, 0, 2, 1, 0, 2, 1, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 2, 0, 1, 2, 0, 1, 2, 0, 1, 0, 0} if !isArrayEqual([][]int64{b}, [][]int64{c}) {
c := []int64{1, 0, 2, 1, 0, 2, 1, 0, 2, 1, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 2, 0, 1, 2, 0, 1, 2, 0, 1, 0, 0}
if !isArrayEqual([][]int64{b}, [][]int64{c}) {
t.Errorf("Fail to get m2 result %v", b)
}
t.Log("b", b)

View file

@ -255,7 +255,7 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) {
// Check m2 exists on chaindb.
// Get secrets and opening at epoc block checkpoint.
if number > 0 && number%contracts.EpocBlockRandomize == 0 {
var candidates [][]int64
var candidates []int64
// Get signers from snapshot.
snap, err := c.GetSnapshot(eth.blockchain, chain.CurrentHeader())
if err != nil {
@ -270,9 +270,7 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) {
if err != nil {
log.Error("Fail to get random m2 from contract.", "error", err)
}
if random != nil {
candidates = append(candidates, random)
}
candidates = append(candidates, random)
}
}
@ -284,7 +282,6 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) {
if len(m2) > 0 {
header.Validators = contracts.BuildValidatorFromM2(m2)
}
log.Debug("list m2", "M2", m2)
}
return nil