diff --git a/blockchain/ethereum/ethereum.go b/blockchain/ethereum/ethereum.go index 849677d5..23d50133 100644 --- a/blockchain/ethereum/ethereum.go +++ b/blockchain/ethereum/ethereum.go @@ -3,12 +3,15 @@ package ethereum import ( "bufio" "context" + "crypto/ecdsa" "encoding/json" "errors" "fmt" "io/ioutil" + "log" "math/big" "os" + "path/filepath" "strings" "time" @@ -192,19 +195,103 @@ func NewEndpoint( return eth, nil } +// NewEndpointWithAccount creates a new Ethereum abstraction +func NewEndpointWithAccount(endpoint string, workingDir string, accountInput map[accounts.Account]*ecdsa.PrivateKey, finalityDelay uint64, txMaxGasFeeAllowedInGwei uint64, endpointMinimumPeers uint32) (*Details, error) { + + logger := logging.GetLogger("ethereum") + log.Printf("********** At this point account pk map addresses looks like this") + var ownerAccount accounts.Account + for k := range accountInput { + log.Printf("%s", k.Address.String()) + if k.Address.String() == "0x546F99F244b7B58B855330AE0E2BC1b30b41302F" { + ownerAccount = k + } + } + log.Printf("********** 4 - Owner account address in NewEndpointWithAccount() method %s", ownerAccount.Address.String()) + + if txMaxGasFeeAllowedInGwei < constants.EthereumMinGasFeeAllowedInGwei { + return nil, fmt.Errorf("txMaxGasFeeAllowedInGwei should be greater than %v Gwei", constants.EthereumMinGasFeeAllowedInGwei) + } + + txMaxGasFeeAllowedInWei := new(big.Int).Mul(new(big.Int).SetUint64(txMaxGasFeeAllowedInGwei), new(big.Int).SetUint64(1_000_000_000)) + + accountList := make(map[common.Address]accounts.Account) + passCodes := make(map[common.Address]string) + + eth := &Details{ + endpoint: endpoint, + logger: logger, + accounts: accountList, + keys: make(map[common.Address]*keystore.Key), + passCodes: passCodes, + finalityDelay: finalityDelay, + txMaxGasFeeAllowed: txMaxGasFeeAllowedInWei, + } + + keystorePath := filepath.Join(workingDir, "scripts", "generated", "keystores", "keys") + eth.keystore = keystore.NewKeyStore(keystorePath, keystore.StandardScryptN, keystore.StandardScryptP) + + // Load accounts + passCodes + eth.loadAccounts(keystorePath) + //eth.loadWallets(accountInput, workingDir) + + //for k := range accountInput { + // accountList[k.Address] = k + // passCodes[k.Address] = "abc123" + //} + //passcode, _ := eth.passCodes[ownerAccount.Address] + + eth.addEthereumPasscodes(accountInput) + + log.Printf("********** 7 - Unlock owner account %s with passphrase %s", ownerAccount.Address.String(), eth.passCodes[ownerAccount.Address]) + err := eth.keystore.Unlock(ownerAccount, eth.passCodes[ownerAccount.Address]) + if err != nil { + return nil, err + } + + eth.contracts = NewContractDetails(eth) + eth.setDefaultAccount(ownerAccount) + // TODO - what is the difference with the one above + //err := eth.unlockAccount(ownerAccount) + //if err != nil { + // return nil, fmt.Errorf("Could not unlock account: %v", err) + //} + + // Low level rpc client + ctx, cancel := context.WithTimeout(context.Background(), constants.MonitorTimeout) + defer cancel() + rpcClient, rpcErr := rpc.DialContext(ctx, endpoint) + if rpcErr != nil { + return nil, fmt.Errorf("Error in NewEndpoint at rpc.DialContext: %v", rpcErr) + } + eth.rpcClient = rpcClient + ethClient := ethclient.NewClient(rpcClient) + eth.client = ethClient + + chainId, err := ethClient.ChainID(ctx) + if err != nil { + return nil, fmt.Errorf("Error in NewEndpoint at ethClient.ChainID: %v", err) + } + eth.chainID = chainId + + logger.Debug("Completed initialization") + return eth, nil +} + //LoadAccounts Scans the directory specified and loads all the accounts found -func (eth *Details) loadAccounts(directoryPath string) { - logger := eth.logger +func (eth *Details) loadAccounts(keystorePath string) { - logger.Infof("LoadAccounts(\"%v\")...", directoryPath) - ks := keystore.NewKeyStore(directoryPath, keystore.StandardScryptN, keystore.StandardScryptP) + log.Printf("********** 5 - Load accounts from %s", keystorePath) + ks := keystore.NewKeyStore(keystorePath, keystore.StandardScryptN, keystore.StandardScryptP) accts := make(map[common.Address]accounts.Account, 10) acctIndex := make(map[common.Address]int, 10) + log.Printf("********** 6 - Keystore contains %d wallets", len(ks.Wallets())) + var index int for _, wallet := range ks.Wallets() { for _, account := range wallet.Accounts() { - logger.Infof("... found account %v", account.Address.Hex()) + log.Printf(" accts[%s] = account value", account.Address.String()) accts[account.Address] = account acctIndex[account.Address] = index index++ @@ -216,6 +303,26 @@ func (eth *Details) loadAccounts(directoryPath string) { eth.keystore = ks } +//LoadAccounts Scans the directory specified and loads all the accounts found +func (eth *Details) loadWallets(accountMap map[accounts.Account]*ecdsa.PrivateKey, workingDir string) { + + ks := keystore.NewKeyStore(workingDir, keystore.StandardScryptN, keystore.StandardScryptP) + accts := make(map[common.Address]accounts.Account, 10) + acctIndex := make(map[common.Address]int, 10) + + var index int + for k := range accountMap { + accts[k.Address] = k + acctIndex[k.Address] = index + acctIndex[k.Address] = index + index++ + } + + eth.accounts = accts + eth.accountIndex = acctIndex + eth.keystore = ks +} + // LoadPasscodes loads the specified passcode file func (eth *Details) loadPassCodes(filePath string) error { logger := eth.logger @@ -250,20 +357,43 @@ func (eth *Details) loadPassCodes(filePath string) error { return nil } +// LoadPasscodes loads the specified passcode file +func (eth *Details) addEthereumPasscodes(accountMap map[accounts.Account]*ecdsa.PrivateKey) { + passcodes := make(map[common.Address]string) + for k := range accountMap { + passcodes[common.HexToAddress(k.Address.String())] = "abc123" + } + eth.passCodes = passcodes +} + // UnlockAccount unlocks the previously loaded account using the previously loaded passCodes func (eth *Details) unlockAccount(acct accounts.Account) error { eth.logger.Infof("Unlocking account address:%v", acct.Address.String()) + for k, v := range eth.passCodes { + log.Printf("%s=%s", k.String(), v) + } passCode, passCodeFound := eth.passCodes[acct.Address] if !passCodeFound { return ErrPassCodeNotFound } - err := eth.keystore.Unlock(acct, passCode) - if err != nil { - return err - } + //addr := common.Address{} + //addr.SetBytes([]byte("546F99F244b7B58B855330AE0E2BC1b30b41302F")) + // + //create a DkgState obj + //acct = accounts.Account{ + // Address: addr, + // URL: accounts.URL{ + // Scheme: "http", + // Path: "", + // }, + //} + //err := eth.keystore.Unlock(acct, "abc123") + //if err != nil { + // return err + //} // Open the account key file keyJSON, err := ioutil.ReadFile(acct.URL.Path) diff --git a/blockchain/ethereum/testing/ethereum_test.go b/blockchain/ethereum/testing/ethereum_test.go index 75672056..68e4bfb0 100644 --- a/blockchain/ethereum/testing/ethereum_test.go +++ b/blockchain/ethereum/testing/ethereum_test.go @@ -3,199 +3,122 @@ package ethereum import ( - "context" - "errors" - "fmt" - "io/fs" - "math" - "math/big" - "net" - "testing" - "time" - - "github.com/MadBase/MadNet/blockchain/ethereum" "github.com/MadBase/MadNet/blockchain/testutils" + "testing" - "github.com/MadBase/MadNet/logging" - "github.com/sirupsen/logrus" "github.com/stretchr/testify/assert" ) -func setupEthereum(t *testing.T, n int) ethereum.Network { - logging.GetLogger("ethereum").SetLevel(logrus.InfoLevel) - - ecdsaPrivateKeys, _ := testutils.InitializePrivateKeysAndAccounts(n) - eth := testutils.ConnectSimulatorEndpoint(t, ecdsaPrivateKeys, 1000*time.Millisecond) - assert.NotNil(t, eth) - - acct := eth.GetDefaultAccount() - assert.Nil(t, eth.UnlockAccount(acct)) - - return eth -} - func TestEthereum_AccountsFound(t *testing.T) { - eth := setupEthereum(t, 4) + eth := testutils.GetEthereumNetwork(t, false, 4, "") defer eth.Close() accountList := eth.GetKnownAccounts() - for _, acct := range accountList { - - err := eth.UnlockAccount(acct) - assert.Nilf(t, err, "Not able to unlock account: %v", acct.Address) - - _, err = eth.GetAccountKeys(acct.Address) + _, err := eth.GetAccountKeys(acct.Address) assert.Nilf(t, err, "Not able to get keys for account: %v", acct.Address) } - } -func TestEthereum_HardhatNode(t *testing.T) { - privateKeys, _ := testutils.InitializePrivateKeysAndAccounts(4) - - eth, err := ethereum.NewSimulator( - privateKeys, - 6, - 10*time.Second, - 30*time.Second, - 0, - big.NewInt(math.MaxInt64), - 50, - math.MaxInt64) - defer func() { - err := eth.Close() - if err != nil { - t.Fatalf("error closing eth: %v", err) - } - }() - - assert.Nil(t, err, "Failed to build Ethereum endpoint...") - - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - - // Unlock the default account and use it to deploy contracts - deployAccount := eth.GetDefaultAccount() - err = eth.UnlockAccount(deployAccount) - assert.Nil(t, err, "Failed to unlock default account") - - t.Logf("deploy account: %v", deployAccount.Address.String()) - - err = testutils.StartHardHatNode(eth) - if err != nil { - t.Fatalf("error starting hardhat node: %v", err) - } - - t.Logf("waiting on hardhat node to start...") - - err = testutils.WaitForHardHatNode(ctx) - if err != nil { - t.Fatalf("error: %v", err) - } - - t.Logf("done testing") -} - -func TestEthereum_NewEthereumEndpoint(t *testing.T) { - - eth := setupEthereum(t, 4) - defer eth.Close() - - type args struct { - endpoint string - pathKeystore string - pathPasscodes string - defaultAccount string - timeout time.Duration - retryCount int - retryDelay time.Duration - finalityDelay int - txFeePercentageToIncrease int - getTxMaxGasFeeAllowedInGwei uint64 - } - tests := []struct { - name string - args args - want bool - wantErr assert.ErrorAssertionFunc - }{ - - { - name: "Create new ethereum endpoint failing with passcode file not found", - args: args{"", "", "", "", 0, 0, 0, 0, 0, 0}, - want: false, - wantErr: func(t assert.TestingT, err error, i ...interface{}) bool { - _, ok := err.(*fs.PathError) - if !ok { - t.Errorf("Failing test with an unexpected error") - } - return ok - }, - }, - { - name: "Create new ethereum endpoint failing with specified account not found", - args: args{"", "", "../assets/test/passcodes.txt", "", 0, 0, 0, 0, 0, 0}, - want: false, - wantErr: func(t assert.TestingT, err error, i ...interface{}) bool { - if !errors.Is(err, ethereum.ErrAccountNotFound) { - t.Errorf("Failing test with an unexpected error") - } - return true - }, - }, - { - name: "Create new ethereum endpoint failing on Dial Context", - args: args{ - eth.GetEndpoint(), - "../assets/test/keys", - "../assets/test/passcodes.txt", - eth.GetDefaultAccount().Address.String(), - eth.Timeout(), - eth.RetryCount(), - eth.RetryDelay(), - int(eth.GetFinalityDelay()), - eth.GetTxFeePercentageToIncrease(), - eth.GetTxMaxGasFeeAllowedInGwei(), - }, - want: false, - wantErr: func(t assert.TestingT, err error, i ...interface{}) bool { - _, ok := err.(*net.OpError) - if !ok { - t.Errorf("Failing test with an unexpected error") - } - return ok - }, - }, - { - name: "Create new ethereum endpoint returning EthereumDetails", - args: args{ - "http://localhost:8545", - "../assets/test/keys", - "../assets/test/passcodes.txt", - eth.GetDefaultAccount().Address.String(), - eth.Timeout(), - eth.RetryCount(), - eth.RetryDelay(), - int(eth.GetFinalityDelay()), - eth.GetTxFeePercentageToIncrease(), - eth.GetTxMaxGasFeeAllowedInGwei(), - }, - want: true, - wantErr: func(t assert.TestingT, err error, i ...interface{}) bool { - return true - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got, err := ethereum.NewEndpoint(tt.args.endpoint, tt.args.pathKeystore, tt.args.pathPasscodes, tt.args.defaultAccount, tt.args.timeout, tt.args.retryCount, tt.args.retryDelay, tt.args.txFeePercentageToIncrease, tt.args.getTxMaxGasFeeAllowedInGwei) - if !tt.wantErr(t, err, fmt.Sprintf("NewEthereumEndpoint(%v, %v, %v, %v, %v, %v, %v, %v, %v, %v, %v)", tt.args.endpoint, tt.args.pathKeystore, tt.args.pathPasscodes, tt.args.defaultAccount, tt.args.timeout, tt.args.retryCount, tt.args.retryDelay, tt.args.txFeePercentageToIncrease, tt.args.getTxMaxGasFeeAllowedInGwei)) { - return - } - if tt.want { - assert.NotNilf(t, got, "Ethereum Details must not be nil") - } - }) - } -} +//func TestEthereum_NewEthereumEndpoint(t *testing.T) { +// +// eth := setupEthereum(t, 4) +// defer eth.Close() +// +// type args struct { +// endpoint string +// pathKeystore string +// pathPasscodes string +// defaultAccount string +// timeout time.Duration +// retryCount int +// retryDelay time.Duration +// finalityDelay int +// txFeePercentageToIncrease int +// getTxMaxGasFeeAllowedInGwei uint64 +// } +// tests := []struct { +// name string +// args args +// want bool +// wantErr assert.ErrorAssertionFunc +// }{ +// +// { +// name: "Create new ethereum endpoint failing with passcode file not found", +// args: args{"", "", "", "", 0, 0, 0, 0, 0, 0}, +// want: false, +// wantErr: func(t assert.TestingT, err error, i ...interface{}) bool { +// _, ok := err.(*fs.PathError) +// if !ok { +// t.Errorf("Failing test with an unexpected error") +// } +// return ok +// }, +// }, +// { +// name: "Create new ethereum endpoint failing with specified account not found", +// args: args{"", "", "../assets/test/passcodes.txt", "", 0, 0, 0, 0, 0, 0}, +// want: false, +// wantErr: func(t assert.TestingT, err error, i ...interface{}) bool { +// if !errors.Is(err, ethereum.ErrAccountNotFound) { +// t.Errorf("Failing test with an unexpected error") +// } +// return true +// }, +// }, +// { +// name: "Create new ethereum endpoint failing on Dial Context", +// args: args{ +// eth.GetEndpoint(), +// "../assets/test/keys", +// "../assets/test/passcodes.txt", +// eth.GetDefaultAccount().Address.String(), +// eth.Timeout(), +// eth.RetryCount(), +// eth.RetryDelay(), +// int(eth.GetFinalityDelay()), +// eth.GetTxFeePercentageToIncrease(), +// eth.GetTxMaxGasFeeAllowedInGwei(), +// }, +// want: false, +// wantErr: func(t assert.TestingT, err error, i ...interface{}) bool { +// _, ok := err.(*net.OpError) +// if !ok { +// t.Errorf("Failing test with an unexpected error") +// } +// return ok +// }, +// }, +// { +// name: "Create new ethereum endpoint returning EthereumDetails", +// args: args{ +// "http://localhost:8545", +// "../assets/test/keys", +// "../assets/test/passcodes.txt", +// eth.GetDefaultAccount().Address.String(), +// eth.Timeout(), +// eth.RetryCount(), +// eth.RetryDelay(), +// int(eth.GetFinalityDelay()), +// eth.GetTxFeePercentageToIncrease(), +// eth.GetTxMaxGasFeeAllowedInGwei(), +// }, +// want: true, +// wantErr: func(t assert.TestingT, err error, i ...interface{}) bool { +// return true +// }, +// }, +// } +// for _, tt := range tests { +// t.Run(tt.name, func(t *testing.T) { +// got, err := ethereum.NewEndpoint(tt.args.endpoint, tt.args.pathKeystore, tt.args.pathPasscodes, tt.args.defaultAccount, tt.args.timeout, tt.args.retryCount, tt.args.retryDelay, tt.args.txFeePercentageToIncrease, tt.args.getTxMaxGasFeeAllowedInGwei) +// if !tt.wantErr(t, err, fmt.Sprintf("NewEthereumEndpoint(%v, %v, %v, %v, %v, %v, %v, %v, %v, %v, %v)", tt.args.endpoint, tt.args.pathKeystore, tt.args.pathPasscodes, tt.args.defaultAccount, tt.args.timeout, tt.args.retryCount, tt.args.retryDelay, tt.args.txFeePercentageToIncrease, tt.args.getTxMaxGasFeeAllowedInGwei)) { +// return +// } +// if tt.want { +// assert.NotNilf(t, got, "Ethereum Details must not be nil") +// } +// }) +// } +//} diff --git a/blockchain/executor/tasks/dkg/completion_test.go b/blockchain/executor/tasks/dkg/completion_test.go index b7a551c6..6a580878 100644 --- a/blockchain/executor/tasks/dkg/completion_test.go +++ b/blockchain/executor/tasks/dkg/completion_test.go @@ -4,27 +4,24 @@ package dkg_test import ( "context" - "testing" - "time" - "github.com/MadBase/MadNet/blockchain/executor/tasks/dkg" "github.com/MadBase/MadNet/blockchain/executor/tasks/dkg/state" dkgTestUtils "github.com/MadBase/MadNet/blockchain/executor/tasks/dkg/testutils" "github.com/MadBase/MadNet/blockchain/monitor/events" "github.com/MadBase/MadNet/blockchain/testutils" - + "github.com/MadBase/MadNet/blockchain/testutils/cmd" "github.com/MadBase/MadNet/logging" "github.com/sirupsen/logrus" "github.com/stretchr/testify/assert" + "os" + "testing" ) // We complete everything correctly, happy path func TestCompletion_Group_1_AllGood(t *testing.T) { n := 4 - - err := testutils.InitializeValidatorFiles(5) + _, err := testutils.BuildTestEnvironment(t, n) assert.Nil(t, err) - suite := dkgTestUtils.StartFromMPKSubmissionPhase(t, n, 100) defer suite.Eth.Close() ctx := context.Background() @@ -40,7 +37,6 @@ func TestCompletion_Group_1_AllGood(t *testing.T) { err = suite.GpkjSubmissionTasks[idx].DoWork(ctx, logger, eth) assert.Nil(t, err) - eth.Commit() assert.True(t, suite.GpkjSubmissionTasks[idx].Success) } @@ -59,7 +55,7 @@ func TestCompletion_Group_1_AllGood(t *testing.T) { } // Advance to Completion phase - testutils.AdvanceTo(t, eth, completionStart) + testutils.AdvanceTo(eth, completionStart) for idx := 0; idx < n; idx++ { state := dkgStates[idx] @@ -85,8 +81,9 @@ func TestCompletion_Group_1_AllGood(t *testing.T) { } func TestCompletion_Group_1_StartFromCompletion(t *testing.T) { + workingDir := cmd.CreateTestWorkingFolder() n := 4 - suite := dkgTestUtils.StartFromCompletion(t, n, 100) + suite := dkgTestUtils.StartFromCompletion(t, n, 100, workingDir) defer suite.Eth.Close() ctx := context.Background() eth := suite.Eth @@ -106,7 +103,6 @@ func TestCompletion_Group_1_StartFromCompletion(t *testing.T) { if amILeading { hasLeader = true err = task.DoWork(ctx, logger, eth) - eth.Commit() assert.Nil(t, err) assert.False(t, task.ShouldRetry(ctx, logger, eth)) assert.True(t, task.Success) @@ -135,11 +131,15 @@ func TestCompletion_Group_1_StartFromCompletion(t *testing.T) { // This test is meant to raise an error resulting from an invalid argument // for the Ethereum interface. func TestCompletion_Group_2_Bad1(t *testing.T) { - n := 4 - ecdsaPrivateKeys, _ := testutils.InitializePrivateKeysAndAccounts(n) + workingDir, err := cmd.CreateTempFolder() + if err != nil { + assert.Fail(t, "Failing creating temporary folder", err) + } + defer os.Remove(workingDir) + logger := logging.GetLogger("ethereum") logger.SetLevel(logrus.DebugLevel) - eth := testutils.ConnectSimulatorEndpoint(t, ecdsaPrivateKeys, 333*time.Millisecond) + eth := testutils.GetEthereumNetwork(t, false, 4, workingDir, nil) defer eth.Close() acct := eth.GetKnownAccounts()[0] @@ -152,17 +152,20 @@ func TestCompletion_Group_2_Bad1(t *testing.T) { task := dkg.NewCompletionTask(state, 1, 100) log := logger.WithField("TaskID", "foo") - err := task.Initialize(ctx, log, eth) + err = task.Initialize(ctx, log, eth) assert.NotNil(t, err) } // We test to ensure that everything behaves correctly. func TestCompletion_Group_2_Bad2(t *testing.T) { - n := 4 - ecdsaPrivateKeys, _ := testutils.InitializePrivateKeysAndAccounts(n) + workingDir, err := cmd.CreateTempFolder() + if err != nil { + assert.Fail(t, "Failing creating temporary folder", err) + } + defer os.Remove(workingDir) logger := logging.GetLogger("ethereum") logger.SetLevel(logrus.DebugLevel) - eth := testutils.ConnectSimulatorEndpoint(t, ecdsaPrivateKeys, 333*time.Millisecond) + eth := testutils.GetEthereumNetwork(t, false, 4, workingDir, nil) defer eth.Close() acct := eth.GetKnownAccounts()[0] @@ -175,7 +178,7 @@ func TestCompletion_Group_2_Bad2(t *testing.T) { log := logger.WithField("TaskID", "foo") task := dkg.NewCompletionTask(state, 1, 100) - err := task.Initialize(ctx, log, eth) + err = task.Initialize(ctx, log, eth) if err == nil { t.Fatal("Should have raised error") } @@ -183,8 +186,9 @@ func TestCompletion_Group_2_Bad2(t *testing.T) { // We complete everything correctly, but we do not complete in time func TestCompletion_Group_2_Bad3(t *testing.T) { + workingDir := cmd.CreateTestWorkingFolder() n := 4 - suite := dkgTestUtils.StartFromMPKSubmissionPhase(t, n, 100) + suite := dkgTestUtils.StartFromMPKSubmissionPhase(t, n, 100, workingDir) defer suite.Eth.Close() ctx := context.Background() eth := suite.Eth @@ -200,7 +204,6 @@ func TestCompletion_Group_2_Bad3(t *testing.T) { err = tasksVec[idx].DoWork(ctx, logger, eth) assert.Nil(t, err) - eth.Commit() assert.True(t, tasksVec[idx].Success) } @@ -217,11 +220,10 @@ func TestCompletion_Group_2_Bad3(t *testing.T) { } // Advance to Completion phase - testutils.AdvanceTo(t, eth, completionStart) + testutils.AdvanceTo(eth, completionStart) // Advance to end of Completion phase - testutils.AdvanceTo(t, eth, completionEnd) - eth.Commit() + testutils.AdvanceTo(eth, completionEnd) err = completionTasks[0].Initialize(ctx, logger, eth) if err != nil { @@ -234,8 +236,9 @@ func TestCompletion_Group_2_Bad3(t *testing.T) { } func TestCompletion_Group_3_ShouldRetry_returnsFalse(t *testing.T) { + workingDir := cmd.CreateTestWorkingFolder() n := 4 - suite := dkgTestUtils.StartFromCompletion(t, n, 40) + suite := dkgTestUtils.StartFromCompletion(t, n, 40, workingDir) defer suite.Eth.Close() ctx := context.Background() eth := suite.Eth @@ -271,8 +274,9 @@ func TestCompletion_Group_3_ShouldRetry_returnsFalse(t *testing.T) { } func TestCompletion_Group_3_ShouldRetry_returnsTrue(t *testing.T) { + workingDir := cmd.CreateTestWorkingFolder() n := 4 - suite := dkgTestUtils.StartFromMPKSubmissionPhase(t, n, 100) + suite := dkgTestUtils.StartFromMPKSubmissionPhase(t, n, 100, workingDir) defer suite.Eth.Close() ctx := context.Background() eth := suite.Eth @@ -286,7 +290,6 @@ func TestCompletion_Group_3_ShouldRetry_returnsTrue(t *testing.T) { err = suite.GpkjSubmissionTasks[idx].DoWork(ctx, logger, eth) assert.Nil(t, err) - eth.Commit() assert.True(t, suite.GpkjSubmissionTasks[idx].Success) } @@ -305,8 +308,7 @@ func TestCompletion_Group_3_ShouldRetry_returnsTrue(t *testing.T) { } // Advance to Completion phase - testutils.AdvanceTo(t, eth, completionStart) - eth.Commit() + testutils.AdvanceTo(eth, completionStart) err = completionTasks[0].Initialize(ctx, logger, eth) assert.Nil(t, err) diff --git a/blockchain/executor/tasks/dkg/dispute_gpkj_test.go b/blockchain/executor/tasks/dkg/dispute_gpkj_test.go index 6d6d2b3d..f8421cd8 100644 --- a/blockchain/executor/tasks/dkg/dispute_gpkj_test.go +++ b/blockchain/executor/tasks/dkg/dispute_gpkj_test.go @@ -4,6 +4,7 @@ package dkg_test import ( "context" + "github.com/MadBase/MadNet/blockchain/testutils/cmd" "math/big" "testing" @@ -20,9 +21,10 @@ import ( // We test to ensure that everything behaves correctly. func TestGPKjDispute_NoBadGPKj(t *testing.T) { + workingDir := cmd.CreateTestWorkingFolder() n := 5 unsubmittedGPKj := 0 - suite := dkgTestUtils.StartFromMPKSubmissionPhase(t, n, 100) + suite := dkgTestUtils.StartFromMPKSubmissionPhase(t, n, 100, workingDir) defer suite.Eth.Close() accounts := suite.Eth.GetKnownAccounts() ctx := context.Background() @@ -41,7 +43,6 @@ func TestGPKjDispute_NoBadGPKj(t *testing.T) { err = gpkjSubmissionTask.DoWork(ctx, logger, eth) assert.Nil(t, err) - eth.Commit() assert.True(t, gpkjSubmissionTask.Success) // event @@ -61,7 +62,7 @@ func TestGPKjDispute_NoBadGPKj(t *testing.T) { assert.Nil(t, err) disputePhaseAt := currentHeight + suite.DKGStates[0].ConfirmationLength - testutils.AdvanceTo(t, eth, disputePhaseAt) + testutils.AdvanceTo(eth, disputePhaseAt) // Do dispute bad gpkj task for idx := 0; idx < n; idx++ { @@ -74,7 +75,6 @@ func TestGPKjDispute_NoBadGPKj(t *testing.T) { err = disputeBadGPKjTask.DoWork(ctx, logger, eth) assert.Nil(t, err) - eth.Commit() assert.True(t, disputeBadGPKjTask.Success) } @@ -86,9 +86,10 @@ func TestGPKjDispute_NoBadGPKj(t *testing.T) { // Here, we have a malicious gpkj submission. func TestGPKjDispute_1Invalid(t *testing.T) { + workingDir := cmd.CreateTestWorkingFolder() n := 5 unsubmittedGPKj := 0 - suite := dkgTestUtils.StartFromMPKSubmissionPhase(t, n, 100) + suite := dkgTestUtils.StartFromMPKSubmissionPhase(t, n, 100, workingDir) defer suite.Eth.Close() accounts := suite.Eth.GetKnownAccounts() ctx := context.Background() @@ -120,7 +121,6 @@ func TestGPKjDispute_1Invalid(t *testing.T) { err = gpkjSubmissionTask.DoWork(ctx, logger, eth) assert.Nil(t, err) - eth.Commit() assert.True(t, gpkjSubmissionTask.Success) // event @@ -140,7 +140,7 @@ func TestGPKjDispute_1Invalid(t *testing.T) { assert.Nil(t, err) disputePhaseAt := currentHeight + suite.DKGStates[0].ConfirmationLength - testutils.AdvanceTo(t, eth, disputePhaseAt) + testutils.AdvanceTo(eth, disputePhaseAt) // Do dispute bad gpkj task for idx := 0; idx < n; idx++ { @@ -153,7 +153,6 @@ func TestGPKjDispute_1Invalid(t *testing.T) { err = disputeBadGPKjTask.DoWork(ctx, logger, eth) assert.Nil(t, err) - eth.Commit() assert.True(t, disputeBadGPKjTask.Success) } @@ -166,9 +165,10 @@ func TestGPKjDispute_1Invalid(t *testing.T) { // We test to ensure that everything behaves correctly. // Here, we have a malicious accusation. func TestGPKjDispute_GoodMaliciousAccusation(t *testing.T) { + workingDir := cmd.CreateTestWorkingFolder() n := 5 unsubmittedGPKj := 0 - suite := dkgTestUtils.StartFromMPKSubmissionPhase(t, n, 100) + suite := dkgTestUtils.StartFromMPKSubmissionPhase(t, n, 100, workingDir) defer suite.Eth.Close() accounts := suite.Eth.GetKnownAccounts() ctx := context.Background() @@ -187,7 +187,6 @@ func TestGPKjDispute_GoodMaliciousAccusation(t *testing.T) { err = gpkjSubmissionTask.DoWork(ctx, logger, eth) assert.Nil(t, err) - eth.Commit() assert.True(t, gpkjSubmissionTask.Success) // event @@ -207,7 +206,7 @@ func TestGPKjDispute_GoodMaliciousAccusation(t *testing.T) { assert.Nil(t, err) disputePhaseAt := currentHeight + suite.DKGStates[0].ConfirmationLength - testutils.AdvanceTo(t, eth, disputePhaseAt) + testutils.AdvanceTo(eth, disputePhaseAt) // Do dispute bad gpkj task badAccuserIdx := 0 @@ -225,7 +224,6 @@ func TestGPKjDispute_GoodMaliciousAccusation(t *testing.T) { err = disputeBadGPKjTask.DoWork(ctx, logger, eth) assert.Nil(t, err) - eth.Commit() assert.True(t, disputeBadGPKjTask.Success) } diff --git a/blockchain/executor/tasks/dkg/dispute_missing_gpkj_test.go b/blockchain/executor/tasks/dkg/dispute_missing_gpkj_test.go index 19971c6f..a38b5155 100644 --- a/blockchain/executor/tasks/dkg/dispute_missing_gpkj_test.go +++ b/blockchain/executor/tasks/dkg/dispute_missing_gpkj_test.go @@ -4,6 +4,7 @@ package dkg_test import ( "context" + "github.com/MadBase/MadNet/blockchain/testutils/cmd" "testing" dkgTestUtils "github.com/MadBase/MadNet/blockchain/executor/tasks/dkg/testutils" @@ -14,9 +15,10 @@ import ( ) func TestDisputeMissingGPKjTask_Group_1_FourUnsubmittedGPKj_DoWork_Success(t *testing.T) { + workingDir := cmd.CreateTestWorkingFolder() n := 10 unsubmittedGPKj := 4 - suite := dkgTestUtils.StartFromMPKSubmissionPhase(t, n, 100) + suite := dkgTestUtils.StartFromMPKSubmissionPhase(t, n, 100, workingDir) defer suite.Eth.Close() accounts := suite.Eth.GetKnownAccounts() ctx := context.Background() @@ -36,8 +38,6 @@ func TestDisputeMissingGPKjTask_Group_1_FourUnsubmittedGPKj_DoWork_Success(t *te assert.Nil(t, err) err = gpkjSubmissionTask.DoWork(ctx, logger, eth) assert.Nil(t, err) - - eth.Commit() assert.True(t, gpkjSubmissionTask.Success) // event @@ -47,7 +47,7 @@ func TestDisputeMissingGPKjTask_Group_1_FourUnsubmittedGPKj_DoWork_Success(t *te } } - testutils.AdvanceTo(t, eth, disputeGPKjStartBlock) + testutils.AdvanceTo(eth, disputeGPKjStartBlock) // Do dispute missing gpkj task for idx := 0; idx < n; idx++ { @@ -57,8 +57,6 @@ func TestDisputeMissingGPKjTask_Group_1_FourUnsubmittedGPKj_DoWork_Success(t *te assert.Nil(t, err) err = disputeMissingGPKjTask.DoWork(ctx, logger, eth) assert.Nil(t, err) - - eth.Commit() assert.True(t, disputeMissingGPKjTask.Success) } @@ -70,9 +68,10 @@ func TestDisputeMissingGPKjTask_Group_1_FourUnsubmittedGPKj_DoWork_Success(t *te } func TestDisputeMissingGPKjTask_Group_1_ShouldRetry_False(t *testing.T) { + workingDir := cmd.CreateTestWorkingFolder() n := 5 unsubmittedKeyShares := 1 - suite := dkgTestUtils.StartFromMPKSubmissionPhase(t, n, 300) + suite := dkgTestUtils.StartFromMPKSubmissionPhase(t, n, 300, workingDir) defer suite.Eth.Close() ctx := context.Background() eth := suite.Eth @@ -90,8 +89,6 @@ func TestDisputeMissingGPKjTask_Group_1_ShouldRetry_False(t *testing.T) { assert.Nil(t, err) err = gpkjSubmissionTask.DoWork(ctx, logger, eth) assert.Nil(t, err) - - eth.Commit() assert.True(t, gpkjSubmissionTask.Success) // event @@ -102,7 +99,7 @@ func TestDisputeMissingGPKjTask_Group_1_ShouldRetry_False(t *testing.T) { } nextPhaseAt := currentHeight + dkgStates[0].PhaseLength - testutils.AdvanceTo(t, eth, nextPhaseAt) + testutils.AdvanceTo(eth, nextPhaseAt) // Do dispute missing gpkj task for idx := 0; idx < n; idx++ { @@ -112,8 +109,6 @@ func TestDisputeMissingGPKjTask_Group_1_ShouldRetry_False(t *testing.T) { assert.Nil(t, err) err = disputeMissingGPKjTask.DoWork(ctx, logger, eth) assert.Nil(t, err) - - eth.Commit() assert.True(t, disputeMissingGPKjTask.Success) shouldRetry := disputeMissingGPKjTask.ShouldRetry(ctx, logger, eth) @@ -122,9 +117,10 @@ func TestDisputeMissingGPKjTask_Group_1_ShouldRetry_False(t *testing.T) { } func TestDisputeMissingGPKjTask_Group_1_ShouldRetry_True(t *testing.T) { + workingDir := cmd.CreateTestWorkingFolder() n := 5 unsubmittedKeyShares := 1 - suite := dkgTestUtils.StartFromMPKSubmissionPhase(t, n, 100) + suite := dkgTestUtils.StartFromMPKSubmissionPhase(t, n, 100, workingDir) defer suite.Eth.Close() ctx := context.Background() eth := suite.Eth @@ -143,7 +139,6 @@ func TestDisputeMissingGPKjTask_Group_1_ShouldRetry_True(t *testing.T) { err = gpkjSubmissionTask.DoWork(ctx, logger, eth) assert.Nil(t, err) - eth.Commit() assert.True(t, gpkjSubmissionTask.Success) // event @@ -154,7 +149,7 @@ func TestDisputeMissingGPKjTask_Group_1_ShouldRetry_True(t *testing.T) { } nextPhaseAt := currentHeight + dkgStates[0].PhaseLength - testutils.AdvanceTo(t, eth, nextPhaseAt) + testutils.AdvanceTo(eth, nextPhaseAt) // Do dispute missing gpkj task for idx := 0; idx < n; idx++ { @@ -169,8 +164,9 @@ func TestDisputeMissingGPKjTask_Group_1_ShouldRetry_True(t *testing.T) { } func TestDisputeMissingGPKjTask_Group_2_ShouldAccuseOneValidatorWhoDidNotDistributeGPKjAndAnotherSubmittedBadGPKj(t *testing.T) { + workingDir := cmd.CreateTestWorkingFolder() n := 5 - suite := dkgTestUtils.StartFromGPKjPhase(t, n, []int{4}, []int{3}, 100) + suite := dkgTestUtils.StartFromGPKjPhase(t, n, []int{4}, []int{3}, 100, workingDir) defer suite.Eth.Close() accounts := suite.Eth.GetKnownAccounts() ctx := context.Background() @@ -186,7 +182,6 @@ func TestDisputeMissingGPKjTask_Group_2_ShouldAccuseOneValidatorWhoDidNotDistrib err = disputeMissingGPKjTask.DoWork(ctx, logger, suite.Eth) assert.Nil(t, err) - suite.Eth.Commit() assert.True(t, disputeMissingGPKjTask.Success) // disputeGPKj @@ -197,7 +192,6 @@ func TestDisputeMissingGPKjTask_Group_2_ShouldAccuseOneValidatorWhoDidNotDistrib err = disputeGPKjTask.DoWork(ctx, logger, suite.Eth) assert.Nil(t, err) - suite.Eth.Commit() assert.True(t, disputeGPKjTask.Success) } @@ -219,8 +213,9 @@ func TestDisputeMissingGPKjTask_Group_2_ShouldAccuseOneValidatorWhoDidNotDistrib } func TestDisputeMissingGPKjTask_Group_2_ShouldAccuseTwoValidatorWhoDidNotDistributeGPKjAndAnotherTwoSubmittedBadGPKj(t *testing.T) { + workingDir := cmd.CreateTestWorkingFolder() n := 5 - suite := dkgTestUtils.StartFromGPKjPhase(t, n, []int{3, 4}, []int{1, 2}, 100) + suite := dkgTestUtils.StartFromGPKjPhase(t, n, []int{3, 4}, []int{1, 2}, 100, workingDir) defer suite.Eth.Close() accounts := suite.Eth.GetKnownAccounts() ctx := context.Background() @@ -236,7 +231,6 @@ func TestDisputeMissingGPKjTask_Group_2_ShouldAccuseTwoValidatorWhoDidNotDistrib err = disputeMissingGPKjTask.DoWork(ctx, logger, suite.Eth) assert.Nil(t, err) - suite.Eth.Commit() assert.True(t, disputeMissingGPKjTask.Success) // disputeGPKj @@ -247,7 +241,6 @@ func TestDisputeMissingGPKjTask_Group_2_ShouldAccuseTwoValidatorWhoDidNotDistrib err = disputeGPKjTask.DoWork(ctx, logger, suite.Eth) assert.Nil(t, err) - suite.Eth.Commit() assert.True(t, disputeGPKjTask.Success) } diff --git a/blockchain/executor/tasks/dkg/dispute_missing_key_shares_test.go b/blockchain/executor/tasks/dkg/dispute_missing_key_shares_test.go index 493a1433..c2ef7ad7 100644 --- a/blockchain/executor/tasks/dkg/dispute_missing_key_shares_test.go +++ b/blockchain/executor/tasks/dkg/dispute_missing_key_shares_test.go @@ -4,6 +4,7 @@ package dkg_test import ( "context" + "github.com/MadBase/MadNet/blockchain/testutils/cmd" "testing" dkgTestUtils "github.com/MadBase/MadNet/blockchain/executor/tasks/dkg/testutils" @@ -14,9 +15,10 @@ import ( ) func TestDisputeMissingKeySharesTask_FourUnsubmittedKeyShare_DoWork_Success(t *testing.T) { + workingDir := cmd.CreateTestWorkingFolder() n := 5 unsubmittedKeyShares := 4 - suite := dkgTestUtils.StartFromShareDistributionPhase(t, n, []int{}, []int{}, 100) + suite := dkgTestUtils.StartFromShareDistributionPhase(t, n, []int{}, []int{}, 100, workingDir) defer suite.Eth.Close() accounts := suite.Eth.GetKnownAccounts() ctx := context.Background() @@ -25,7 +27,7 @@ func TestDisputeMissingKeySharesTask_FourUnsubmittedKeyShare_DoWork_Success(t *t logger := logging.GetLogger("test").WithField("Validator", "") // skip DisputeShareDistribution and move to KeyShareSubmission phase - testutils.AdvanceTo(t, eth, suite.KeyshareSubmissionTasks[0].Start) + testutils.AdvanceTo(eth, suite.KeyshareSubmissionTasks[0].Start) // Do key share submission task for idx := 0; idx < n-unsubmittedKeyShares; idx++ { @@ -37,7 +39,6 @@ func TestDisputeMissingKeySharesTask_FourUnsubmittedKeyShare_DoWork_Success(t *t err = keyshareSubmissionTask.DoWork(ctx, logger, eth) assert.Nil(t, err) - eth.Commit() assert.True(t, keyshareSubmissionTask.Success) // event @@ -54,7 +55,7 @@ func TestDisputeMissingKeySharesTask_FourUnsubmittedKeyShare_DoWork_Success(t *t // advance into the end of KeyShareSubmission phase, // which is the start of DisputeMissingKeyShares phase - testutils.AdvanceTo(t, eth, suite.KeyshareSubmissionTasks[0].End) + testutils.AdvanceTo(eth, suite.KeyshareSubmissionTasks[0].End) // Do dispute missing key share task for idx := 0; idx < n; idx++ { @@ -65,7 +66,6 @@ func TestDisputeMissingKeySharesTask_FourUnsubmittedKeyShare_DoWork_Success(t *t err = disputeMissingKeyshareTask.DoWork(ctx, logger, eth) assert.Nil(t, err) - eth.Commit() assert.True(t, disputeMissingKeyshareTask.Success) } @@ -77,9 +77,10 @@ func TestDisputeMissingKeySharesTask_FourUnsubmittedKeyShare_DoWork_Success(t *t } func TestDisputeMissingKeySharesTask_ShouldRetry_False(t *testing.T) { + workingDir := cmd.CreateTestWorkingFolder() n := 5 unsubmittedKeyShares := 1 - suite := dkgTestUtils.StartFromShareDistributionPhase(t, n, []int{}, []int{}, 40) + suite := dkgTestUtils.StartFromShareDistributionPhase(t, n, []int{}, []int{}, 40, workingDir) defer suite.Eth.Close() ctx := context.Background() eth := suite.Eth @@ -87,7 +88,7 @@ func TestDisputeMissingKeySharesTask_ShouldRetry_False(t *testing.T) { logger := logging.GetLogger("test").WithField("Validator", "") // skip DisputeShareDistribution and move to KeyShareSubmission phase - testutils.AdvanceTo(t, eth, suite.KeyshareSubmissionTasks[0].Start) + testutils.AdvanceTo(eth, suite.KeyshareSubmissionTasks[0].Start) // Do key share submission task for idx := 0; idx < n-unsubmittedKeyShares; idx++ { @@ -99,7 +100,6 @@ func TestDisputeMissingKeySharesTask_ShouldRetry_False(t *testing.T) { err = keyshareSubmissionTask.DoWork(ctx, logger, eth) assert.Nil(t, err) - eth.Commit() assert.True(t, keyshareSubmissionTask.Success) // event @@ -116,7 +116,7 @@ func TestDisputeMissingKeySharesTask_ShouldRetry_False(t *testing.T) { // advance into the end of KeyShareSubmission phase, // which is the start of DisputeMissingKeyShares phase - testutils.AdvanceTo(t, eth, suite.KeyshareSubmissionTasks[0].End) + testutils.AdvanceTo(eth, suite.KeyshareSubmissionTasks[0].End) // Do dispute missing key share task for idx := 0; idx < n; idx++ { @@ -129,16 +129,16 @@ func TestDisputeMissingKeySharesTask_ShouldRetry_False(t *testing.T) { assert.True(t, disputeMissingKeyshareTask.Success) - eth.Commit() shouldRetry := disputeMissingKeyshareTask.ShouldRetry(ctx, logger, eth) assert.False(t, shouldRetry) } } func TestDisputeMissingKeySharesTask_ShouldRetry_True(t *testing.T) { + workingDir := cmd.CreateTestWorkingFolder() n := 5 unsubmittedKeyShares := 1 - suite := dkgTestUtils.StartFromShareDistributionPhase(t, n, []int{}, []int{}, 100) + suite := dkgTestUtils.StartFromShareDistributionPhase(t, n, []int{}, []int{}, 100, workingDir) defer suite.Eth.Close() ctx := context.Background() eth := suite.Eth @@ -146,7 +146,7 @@ func TestDisputeMissingKeySharesTask_ShouldRetry_True(t *testing.T) { logger := logging.GetLogger("test").WithField("Validator", "") // skip DisputeShareDistribution and move to KeyShareSubmission phase - testutils.AdvanceTo(t, eth, suite.KeyshareSubmissionTasks[0].Start) + testutils.AdvanceTo(eth, suite.KeyshareSubmissionTasks[0].Start) // Do key share submission task for idx := 0; idx < n-unsubmittedKeyShares; idx++ { @@ -158,7 +158,6 @@ func TestDisputeMissingKeySharesTask_ShouldRetry_True(t *testing.T) { err = keyshareSubmissionTask.DoWork(ctx, logger, eth) assert.Nil(t, err) - eth.Commit() assert.True(t, keyshareSubmissionTask.Success) // event @@ -175,7 +174,7 @@ func TestDisputeMissingKeySharesTask_ShouldRetry_True(t *testing.T) { // advance into the end of KeyShareSubmission phase, // which is the start of DisputeMissingKeyShares phase - testutils.AdvanceTo(t, eth, suite.KeyshareSubmissionTasks[0].End) + testutils.AdvanceTo(eth, suite.KeyshareSubmissionTasks[0].End) // Do dispute missing key share task for idx := 0; idx < n; idx++ { diff --git a/blockchain/executor/tasks/dkg/dispute_missing_registration_test.go b/blockchain/executor/tasks/dkg/dispute_missing_registration_test.go index 5cae1276..4d5507d7 100644 --- a/blockchain/executor/tasks/dkg/dispute_missing_registration_test.go +++ b/blockchain/executor/tasks/dkg/dispute_missing_registration_test.go @@ -4,6 +4,7 @@ package dkg_test import ( "context" + "github.com/MadBase/MadNet/blockchain/testutils/cmd" "testing" "github.com/MadBase/MadNet/blockchain/executor/tasks/dkg/testutils" @@ -12,9 +13,10 @@ import ( ) func TestDisputeMissingRegistrationTask_Group_1_DoTaskSuccessOneParticipantAccused(t *testing.T) { + workingDir := cmd.CreateTestWorkingFolder() n := 4 d := 1 - suite := testutils.StartFromRegistrationOpenPhase(t, n, d, 100) + suite := testutils.StartFromRegistrationOpenPhase(t, n, d, 100, workingDir) defer suite.Eth.Close() ctx, cancel := context.WithCancel(context.Background()) @@ -30,7 +32,6 @@ func TestDisputeMissingRegistrationTask_Group_1_DoTaskSuccessOneParticipantAccus err = suite.DispMissingRegTasks[idx].DoWork(ctx, logger, suite.Eth) assert.Nil(t, err) - suite.Eth.Commit() assert.True(t, suite.DispMissingRegTasks[idx].Success) } @@ -42,9 +43,10 @@ func TestDisputeMissingRegistrationTask_Group_1_DoTaskSuccessOneParticipantAccus } func TestDisputeMissingRegistrationTask_Group_1_DoTaskSuccessThreeParticipantAccused(t *testing.T) { + workingDir := cmd.CreateTestWorkingFolder() n := 5 d := 3 - suite := testutils.StartFromRegistrationOpenPhase(t, n, d, 100) + suite := testutils.StartFromRegistrationOpenPhase(t, n, d, 100, workingDir) defer suite.Eth.Close() ctx, cancel := context.WithCancel(context.Background()) @@ -60,7 +62,6 @@ func TestDisputeMissingRegistrationTask_Group_1_DoTaskSuccessThreeParticipantAcc err = suite.DispMissingRegTasks[idx].DoWork(ctx, logger, suite.Eth) assert.Nil(t, err) - suite.Eth.Commit() assert.True(t, suite.DispMissingRegTasks[idx].Success) } @@ -72,9 +73,10 @@ func TestDisputeMissingRegistrationTask_Group_1_DoTaskSuccessThreeParticipantAcc } func TestDisputeMissingRegistrationTask_Group_1_DoTaskSuccessAllParticipantsAreBad(t *testing.T) { + workingDir := cmd.CreateTestWorkingFolder() n := 5 d := 5 - suite := testutils.StartFromRegistrationOpenPhase(t, n, d, 100) + suite := testutils.StartFromRegistrationOpenPhase(t, n, d, 100, workingDir) defer suite.Eth.Close() ctx, cancel := context.WithCancel(context.Background()) @@ -90,7 +92,6 @@ func TestDisputeMissingRegistrationTask_Group_1_DoTaskSuccessAllParticipantsAreB err = suite.DispMissingRegTasks[idx].DoWork(ctx, logger, suite.Eth) assert.Nil(t, err) - suite.Eth.Commit() assert.True(t, suite.DispMissingRegTasks[idx].Success) } @@ -102,7 +103,8 @@ func TestDisputeMissingRegistrationTask_Group_1_DoTaskSuccessAllParticipantsAreB } func TestDisputeMissingRegistrationTask_Group_2_ShouldRetryTrue(t *testing.T) { - suite := testutils.StartFromRegistrationOpenPhase(t, 5, 1, 100) + workingDir := cmd.CreateTestWorkingFolder() + suite := testutils.StartFromRegistrationOpenPhase(t, 5, 1, 100, workingDir) defer suite.Eth.Close() ctx, cancel := context.WithCancel(context.Background()) @@ -121,7 +123,8 @@ func TestDisputeMissingRegistrationTask_Group_2_ShouldRetryTrue(t *testing.T) { } func TestDisputeMissingRegistrationTask_Group_2_ShouldNotRetryAfterSuccessfullyAccusingAllMissingParticipants(t *testing.T) { - suite := testutils.StartFromRegistrationOpenPhase(t, 5, 0, 100) + workingDir := cmd.CreateTestWorkingFolder() + suite := testutils.StartFromRegistrationOpenPhase(t, 5, 0, 100, workingDir) defer suite.Eth.Close() ctx, cancel := context.WithCancel(context.Background()) @@ -136,7 +139,6 @@ func TestDisputeMissingRegistrationTask_Group_2_ShouldNotRetryAfterSuccessfullyA err = suite.DispMissingRegTasks[idx].DoWork(ctx, logger, suite.Eth) assert.Nil(t, err) - suite.Eth.Commit() assert.True(t, suite.DispMissingRegTasks[idx].Success) } diff --git a/blockchain/executor/tasks/dkg/dispute_missing_share_distribution_test.go b/blockchain/executor/tasks/dkg/dispute_missing_share_distribution_test.go index ca5ea1c0..6b3a0f36 100644 --- a/blockchain/executor/tasks/dkg/dispute_missing_share_distribution_test.go +++ b/blockchain/executor/tasks/dkg/dispute_missing_share_distribution_test.go @@ -4,6 +4,7 @@ package dkg_test import ( "context" + "github.com/MadBase/MadNet/blockchain/testutils/cmd" "testing" "github.com/MadBase/MadNet/blockchain/executor/tasks/dkg/testutils" @@ -13,8 +14,9 @@ import ( ) func TestDisputeMissingShareDistributionTask_Group_1_ShouldAccuseOneValidatorWhoDidNotDistributeShares(t *testing.T) { + workingDir := cmd.CreateTestWorkingFolder() n := 5 - suite := testutils.StartFromShareDistributionPhase(t, n, []int{4}, []int{}, 100) + suite := testutils.StartFromShareDistributionPhase(t, n, []int{4}, []int{}, 100, workingDir) defer suite.Eth.Close() accounts := suite.Eth.GetKnownAccounts() ctx := context.Background() @@ -28,7 +30,6 @@ func TestDisputeMissingShareDistributionTask_Group_1_ShouldAccuseOneValidatorWho err = task.DoWork(ctx, logger, suite.Eth) assert.Nil(t, err) - suite.Eth.Commit() assert.True(t, task.Success) } @@ -40,8 +41,9 @@ func TestDisputeMissingShareDistributionTask_Group_1_ShouldAccuseOneValidatorWho } func TestDisputeMissingShareDistributionTask_Group_1_ShouldAccuseAllValidatorsWhoDidNotDistributeShares(t *testing.T) { + workingDir := cmd.CreateTestWorkingFolder() n := 5 - suite := testutils.StartFromShareDistributionPhase(t, n, []int{0, 1, 2, 3, 4}, []int{}, 100) + suite := testutils.StartFromShareDistributionPhase(t, n, []int{0, 1, 2, 3, 4}, []int{}, 100, workingDir) defer suite.Eth.Close() accounts := suite.Eth.GetKnownAccounts() ctx := context.Background() @@ -55,7 +57,6 @@ func TestDisputeMissingShareDistributionTask_Group_1_ShouldAccuseAllValidatorsWh err = task.DoWork(ctx, logger, suite.Eth) assert.Nil(t, err) - suite.Eth.Commit() assert.True(t, task.Success) } @@ -67,8 +68,9 @@ func TestDisputeMissingShareDistributionTask_Group_1_ShouldAccuseAllValidatorsWh } func TestDisputeMissingShareDistributionTask_Group_1_ShouldNotAccuseValidatorsWhoDidDistributeShares(t *testing.T) { + workingDir := cmd.CreateTestWorkingFolder() n := 5 - suite := testutils.StartFromShareDistributionPhase(t, n, []int{}, []int{}, 100) + suite := testutils.StartFromShareDistributionPhase(t, n, []int{}, []int{}, 100, workingDir) defer suite.Eth.Close() accounts := suite.Eth.GetKnownAccounts() ctx := context.Background() @@ -94,7 +96,6 @@ func TestDisputeMissingShareDistributionTask_Group_1_ShouldNotAccuseValidatorsWh assert.Nil(t, err) } - suite.Eth.Commit() if idx == n-1 { assert.False(t, task.Success) } else { @@ -110,8 +111,9 @@ func TestDisputeMissingShareDistributionTask_Group_1_ShouldNotAccuseValidatorsWh } func TestDisputeMissingShareDistributionTask_Group_2_DisputeMissingShareDistributionTask_ShouldRetryTrue(t *testing.T) { + workingDir := cmd.CreateTestWorkingFolder() n := 5 - suite := testutils.StartFromShareDistributionPhase(t, n, []int{0}, []int{}, 100) + suite := testutils.StartFromShareDistributionPhase(t, n, []int{0}, []int{}, 100, workingDir) defer suite.Eth.Close() accounts := suite.Eth.GetKnownAccounts() ctx := context.Background() @@ -128,8 +130,9 @@ func TestDisputeMissingShareDistributionTask_Group_2_DisputeMissingShareDistribu } func TestDisputeMissingShareDistributionTask_Group_2_DisputeMissingShareDistributionTask_ShouldRetryFalse(t *testing.T) { + workingDir := cmd.CreateTestWorkingFolder() n := 5 - suite := testutils.StartFromShareDistributionPhase(t, n, []int{}, []int{}, 100) + suite := testutils.StartFromShareDistributionPhase(t, n, []int{}, []int{}, 100, workingDir) defer suite.Eth.Close() accounts := suite.Eth.GetKnownAccounts() ctx := context.Background() @@ -143,7 +146,6 @@ func TestDisputeMissingShareDistributionTask_Group_2_DisputeMissingShareDistribu err = task.DoWork(ctx, logger, suite.Eth) assert.Nil(t, err) - suite.Eth.Commit() assert.True(t, task.Success) } @@ -155,8 +157,9 @@ func TestDisputeMissingShareDistributionTask_Group_2_DisputeMissingShareDistribu } func TestDisputeMissingShareDistributionTask_Group_2_ShouldAccuseOneValidatorWhoDidNotDistributeSharesAndAnotherSubmittedBadShares(t *testing.T) { + workingDir := cmd.CreateTestWorkingFolder() n := 5 - suite := testutils.StartFromShareDistributionPhase(t, n, []int{4}, []int{3}, 100) + suite := testutils.StartFromShareDistributionPhase(t, n, []int{4}, []int{3}, 100, workingDir) defer suite.Eth.Close() accounts := suite.Eth.GetKnownAccounts() ctx := context.Background() @@ -172,7 +175,6 @@ func TestDisputeMissingShareDistributionTask_Group_2_ShouldAccuseOneValidatorWho err = disputeMissingShareDistTask.DoWork(ctx, logger, suite.Eth) assert.Nil(t, err) - suite.Eth.Commit() assert.True(t, disputeMissingShareDistTask.Success) // disputeShareDist @@ -183,7 +185,6 @@ func TestDisputeMissingShareDistributionTask_Group_2_ShouldAccuseOneValidatorWho err = disputeShareDistTask.DoWork(ctx, logger, suite.Eth) assert.Nil(t, err) - suite.Eth.Commit() assert.True(t, disputeShareDistTask.Success) } diff --git a/blockchain/executor/tasks/dkg/dispute_share_distribution_test.go b/blockchain/executor/tasks/dkg/dispute_share_distribution_test.go index 4a343d51..7214f02e 100644 --- a/blockchain/executor/tasks/dkg/dispute_share_distribution_test.go +++ b/blockchain/executor/tasks/dkg/dispute_share_distribution_test.go @@ -4,15 +4,14 @@ package dkg_test import ( "context" - "math/big" - "testing" - "time" - "github.com/MadBase/MadNet/blockchain/executor/tasks/dkg" dkgState "github.com/MadBase/MadNet/blockchain/executor/tasks/dkg/state" dkgTestUtils "github.com/MadBase/MadNet/blockchain/executor/tasks/dkg/testutils" "github.com/MadBase/MadNet/blockchain/monitor/events" "github.com/MadBase/MadNet/blockchain/testutils" + "github.com/MadBase/MadNet/blockchain/testutils/cmd" + "math/big" + "testing" "github.com/MadBase/MadNet/logging" "github.com/ethereum/go-ethereum/common" @@ -22,8 +21,9 @@ import ( // We test to ensure that everything behaves correctly. func TestDisputeShareDistributionTask_Group_1_GoodAllValid(t *testing.T) { + workingDir := cmd.CreateTestWorkingFolder() n := 5 - suite := dkgTestUtils.StartFromShareDistributionPhase(t, n, []int{}, []int{}, 100) + suite := dkgTestUtils.StartFromShareDistributionPhase(t, n, []int{}, []int{}, 100, workingDir) defer suite.Eth.Close() accounts := suite.Eth.GetKnownAccounts() ctx := context.Background() @@ -47,7 +47,6 @@ func TestDisputeShareDistributionTask_Group_1_GoodAllValid(t *testing.T) { err = task.DoWork(ctx, logger, suite.Eth) assert.Nil(t, err) - suite.Eth.Commit() assert.True(t, task.Success) } @@ -71,8 +70,9 @@ func TestDisputeShareDistributionTask_Group_1_GoodAllValid(t *testing.T) { // This causes another validator to submit a dispute against him, // causing a stake-slashing event. func TestDisputeShareDistributionTask_Group_1_GoodMaliciousShare(t *testing.T) { + workingDir := cmd.CreateTestWorkingFolder() n := 5 - suite := dkgTestUtils.StartFromRegistrationOpenPhase(t, n, 0, 100) + suite := dkgTestUtils.StartFromRegistrationOpenPhase(t, n, 0, 100, workingDir) defer suite.Eth.Close() accounts := suite.Eth.GetKnownAccounts() ctx := context.Background() @@ -99,7 +99,6 @@ func TestDisputeShareDistributionTask_Group_1_GoodMaliciousShare(t *testing.T) { err = task.DoWork(ctx, logger, suite.Eth) assert.Nil(t, err) - suite.Eth.Commit() assert.True(t, task.Success) // event @@ -118,7 +117,7 @@ func TestDisputeShareDistributionTask_Group_1_GoodMaliciousShare(t *testing.T) { currentHeight, err := suite.Eth.GetCurrentHeight(ctx) assert.Nil(t, err) nextPhaseAt := currentHeight + suite.DKGStates[0].ConfirmationLength - testutils.AdvanceTo(t, suite.Eth, nextPhaseAt) + testutils.AdvanceTo(suite.Eth, nextPhaseAt) // Do Share Dispute task for idx := 0; idx < n; idx++ { @@ -132,7 +131,6 @@ func TestDisputeShareDistributionTask_Group_1_GoodMaliciousShare(t *testing.T) { err = disputeShareDistributionTask.DoWork(ctx, logger, suite.Eth) assert.Nil(t, err) - suite.Eth.Commit() assert.True(t, disputeShareDistributionTask.Success) } @@ -156,11 +154,10 @@ func TestDisputeShareDistributionTask_Group_1_GoodMaliciousShare(t *testing.T) { // This test is meant to raise an error resulting from an invalid argument // for the Ethereum interface. func TestDisputeShareDistributionTask_Group_1_Bad1(t *testing.T) { - n := 4 - ecdsaPrivateKeys, _ := testutils.InitializePrivateKeysAndAccounts(n) logger := logging.GetLogger("ethereum") logger.SetLevel(logrus.DebugLevel) - eth := testutils.ConnectSimulatorEndpoint(t, ecdsaPrivateKeys, 333*time.Millisecond) + //eth := testutils.GetEthereumNetwork(t, ecdsaPrivateKeys, 333*time.Millisecond) + eth := testutils.GetEthereumNetwork(t, false, 4, "", nil) defer eth.Close() acct := eth.GetKnownAccounts()[0] @@ -183,11 +180,9 @@ func TestDisputeShareDistributionTask_Group_1_Bad1(t *testing.T) { // this should raise an error resulting from not successfully completing // ShareDistribution phase. func TestDisputeShareDistributionTask_Group_2_Bad2(t *testing.T) { - n := 4 - ecdsaPrivateKeys, _ := testutils.InitializePrivateKeysAndAccounts(n) logger := logging.GetLogger("ethereum") logger.SetLevel(logrus.DebugLevel) - eth := testutils.ConnectSimulatorEndpoint(t, ecdsaPrivateKeys, 333*time.Millisecond) + eth := testutils.GetEthereumNetwork(t, false, 4, "", nil) defer eth.Close() accts := eth.GetKnownAccounts() @@ -212,8 +207,9 @@ func TestDisputeShareDistributionTask_Group_2_Bad2(t *testing.T) { } func TestDisputeShareDistributionTask_Group_2_DoRetry_returnsFalse(t *testing.T) { + workingDir := cmd.CreateTestWorkingFolder() n := 5 - suite := dkgTestUtils.StartFromShareDistributionPhase(t, n, []int{}, []int{}, 100) + suite := dkgTestUtils.StartFromShareDistributionPhase(t, n, []int{}, []int{}, 100, workingDir) defer suite.Eth.Close() ctx := context.Background() logger := logging.GetLogger("test").WithField("Validator", "") @@ -235,7 +231,6 @@ func TestDisputeShareDistributionTask_Group_2_DoRetry_returnsFalse(t *testing.T) err = task.DoWork(ctx, logger, suite.Eth) assert.Nil(t, err) - suite.Eth.Commit() assert.True(t, task.Success) } @@ -256,8 +251,9 @@ func TestDisputeShareDistributionTask_Group_2_DoRetry_returnsFalse(t *testing.T) } func TestDisputeShareDistributionTask_Group_2_DoRetry_returnsTrue(t *testing.T) { + workingDir := cmd.CreateTestWorkingFolder() n := 5 - suite := dkgTestUtils.StartFromShareDistributionPhase(t, n, []int{}, []int{}, 100) + suite := dkgTestUtils.StartFromShareDistributionPhase(t, n, []int{}, []int{}, 100, workingDir) defer suite.Eth.Close() ctx := context.Background() logger := logging.GetLogger("test").WithField("Validator", "") @@ -280,14 +276,9 @@ func TestDisputeShareDistributionTask_Group_2_DoRetry_returnsTrue(t *testing.T) err = task.DoWork(ctx, logger, suite.Eth) assert.Nil(t, err) - suite.Eth.Commit() assert.True(t, task.Success) } - suite.Eth.Commit() - suite.Eth.Commit() - suite.Eth.Commit() - // Do Should Retry for idx := 0; idx < n; idx++ { task := suite.DisputeShareDistTasks[idx] diff --git a/blockchain/executor/tasks/dkg/gpkj_submission_test.go b/blockchain/executor/tasks/dkg/gpkj_submission_test.go index e56b0d5e..a0f16dd7 100644 --- a/blockchain/executor/tasks/dkg/gpkj_submission_test.go +++ b/blockchain/executor/tasks/dkg/gpkj_submission_test.go @@ -4,15 +4,14 @@ package dkg_test import ( "context" - "math/big" - "testing" - "time" - "github.com/MadBase/MadNet/blockchain/executor/tasks/dkg" dkgState "github.com/MadBase/MadNet/blockchain/executor/tasks/dkg/state" dkgTestUtils "github.com/MadBase/MadNet/blockchain/executor/tasks/dkg/testutils" "github.com/MadBase/MadNet/blockchain/monitor/interfaces" "github.com/MadBase/MadNet/blockchain/testutils" + "github.com/MadBase/MadNet/blockchain/testutils/cmd" + "math/big" + "testing" "github.com/MadBase/MadNet/logging" "github.com/sirupsen/logrus" @@ -21,8 +20,9 @@ import ( //We test to ensure that everything behaves correctly. func TestGPKjSubmission_Group_1_GoodAllValid(t *testing.T) { + workingDir := cmd.CreateTestWorkingFolder() n := 4 - suite := dkgTestUtils.StartFromMPKSubmissionPhase(t, n, 100) + suite := dkgTestUtils.StartFromMPKSubmissionPhase(t, n, 100, workingDir) defer suite.Eth.Close() accounts := suite.Eth.GetKnownAccounts() ctx := context.Background() @@ -38,7 +38,6 @@ func TestGPKjSubmission_Group_1_GoodAllValid(t *testing.T) { err = tasksVec[idx].DoWork(ctx, logger, eth) assert.Nil(t, err) - eth.Commit() assert.True(t, tasksVec[idx].Success) } @@ -61,11 +60,9 @@ func TestGPKjSubmission_Group_1_GoodAllValid(t *testing.T) { // Here, we submit nil for the state interface; // this should raise an error. func TestGPKjSubmission_Group_1_Bad1(t *testing.T) { - n := 4 - ecdsaPrivateKeys, _ := testutils.InitializePrivateKeysAndAccounts(n) logger := logging.GetLogger("ethereum") logger.SetLevel(logrus.DebugLevel) - eth := testutils.ConnectSimulatorEndpoint(t, ecdsaPrivateKeys, 333*time.Millisecond) + eth := testutils.GetEthereumNetwork(t, false, 4, "", nil) defer eth.Close() acct := eth.GetKnownAccounts()[0] @@ -87,11 +84,9 @@ func TestGPKjSubmission_Group_1_Bad1(t *testing.T) { // Here, we should raise an error because we did not successfully complete // the key share submission phase. func TestGPKjSubmission_Group_1_Bad2(t *testing.T) { - n := 4 - ecdsaPrivateKeys, _ := testutils.InitializePrivateKeysAndAccounts(n) logger := logging.GetLogger("ethereum") logger.SetLevel(logrus.DebugLevel) - eth := testutils.ConnectSimulatorEndpoint(t, ecdsaPrivateKeys, 333*time.Millisecond) + eth := testutils.GetEthereumNetwork(t, false, 4, "", nil) defer eth.Close() acct := eth.GetKnownAccounts()[0] @@ -128,8 +123,9 @@ func TestGPKjSubmission_Group_2_Bad3(t *testing.T) { // that is, attempting to verify initialMessage with the signature // and public key should fail verification. // This should raise an error, as this is not allowed by the protocol. + workingDir := cmd.CreateTestWorkingFolder() n := 4 - suite := dkgTestUtils.StartFromMPKSubmissionPhase(t, n, 100) + suite := dkgTestUtils.StartFromMPKSubmissionPhase(t, n, 100, workingDir) defer suite.Eth.Close() ctx := context.Background() eth := suite.Eth @@ -141,7 +137,6 @@ func TestGPKjSubmission_Group_2_Bad3(t *testing.T) { err := tasksVec[idx].Initialize(ctx, logger, eth) assert.Nil(t, err) - eth.Commit() } // Do GPKj Submission task; this will fail because invalid submission; @@ -158,8 +153,9 @@ func TestGPKjSubmission_Group_2_Bad3(t *testing.T) { } func TestGPKjSubmission_Group_2_ShouldRetry_returnsFalse(t *testing.T) { + workingDir := cmd.CreateTestWorkingFolder() n := 4 - suite := dkgTestUtils.StartFromMPKSubmissionPhase(t, n, 100) + suite := dkgTestUtils.StartFromMPKSubmissionPhase(t, n, 100, workingDir) defer suite.Eth.Close() ctx := context.Background() eth := suite.Eth @@ -173,7 +169,6 @@ func TestGPKjSubmission_Group_2_ShouldRetry_returnsFalse(t *testing.T) { err = tasksVec[idx].DoWork(ctx, logger, eth) assert.Nil(t, err) - eth.Commit() assert.True(t, tasksVec[idx].Success) shouldRetry := tasksVec[idx].ShouldRetry(ctx, logger, eth) @@ -182,8 +177,9 @@ func TestGPKjSubmission_Group_2_ShouldRetry_returnsFalse(t *testing.T) { } func TestGPKjSubmission_Group_2_ShouldRetry_returnsTrue(t *testing.T) { + workingDir := cmd.CreateTestWorkingFolder() n := 4 - suite := dkgTestUtils.StartFromMPKSubmissionPhase(t, n, 100) + suite := dkgTestUtils.StartFromMPKSubmissionPhase(t, n, 100, workingDir) defer suite.Eth.Close() ctx := context.Background() eth := suite.Eth diff --git a/blockchain/executor/tasks/dkg/keyshare_submission_test.go b/blockchain/executor/tasks/dkg/keyshare_submission_test.go index 8d16b77b..dc5235dc 100644 --- a/blockchain/executor/tasks/dkg/keyshare_submission_test.go +++ b/blockchain/executor/tasks/dkg/keyshare_submission_test.go @@ -4,6 +4,7 @@ package dkg_test import ( "context" + "github.com/MadBase/MadNet/blockchain/testutils/cmd" "math/big" "testing" @@ -16,8 +17,9 @@ import ( // We test to ensure that everything behaves correctly. func TestKeyShareSubmission_GoodAllValid(t *testing.T) { + workingDir := cmd.CreateTestWorkingFolder() n := 5 - suite := testutils.StartFromKeyShareSubmissionPhase(t, n, 0, 100) + suite := testutils.StartFromKeyShareSubmissionPhase(t, n, 0, 100, workingDir) defer suite.Eth.Close() accounts := suite.Eth.GetKnownAccounts() ctx := context.Background() @@ -48,9 +50,10 @@ func TestKeyShareSubmission_GoodAllValid(t *testing.T) { // This comes from invalid SecretValue in state. // In practice, this should never arise, though. func TestKeyShareSubmission_Bad3(t *testing.T) { + workingDir := cmd.CreateTestWorkingFolder() n := 5 var phaseLength uint16 = 100 - suite := testutils.StartFromShareDistributionPhase(t, n, []int{}, []int{}, phaseLength) + suite := testutils.StartFromShareDistributionPhase(t, n, []int{}, []int{}, phaseLength, workingDir) defer suite.Eth.Close() //accounts := suite.Eth.GetKnownAccounts() ctx := context.Background() @@ -73,9 +76,10 @@ func TestKeyShareSubmission_Bad3(t *testing.T) { // Here, we mess up KeyShare information before submission // so that we raise an error on submission. func TestKeyShareSubmission_Bad4(t *testing.T) { + workingDir := cmd.CreateTestWorkingFolder() n := 5 var phaseLength uint16 = 100 - suite := testutils.StartFromShareDistributionPhase(t, n, []int{}, []int{}, phaseLength) + suite := testutils.StartFromShareDistributionPhase(t, n, []int{}, []int{}, phaseLength, workingDir) defer suite.Eth.Close() //accounts := suite.Eth.GetKnownAccounts() ctx := context.Background() diff --git a/blockchain/executor/tasks/dkg/mpk_submission_test.go b/blockchain/executor/tasks/dkg/mpk_submission_test.go index 4a7d1666..aaaaf6d4 100644 --- a/blockchain/executor/tasks/dkg/mpk_submission_test.go +++ b/blockchain/executor/tasks/dkg/mpk_submission_test.go @@ -4,14 +4,13 @@ package dkg_test import ( "context" - "math/big" - "testing" - "time" - "github.com/MadBase/MadNet/blockchain/executor/tasks/dkg" dkgState "github.com/MadBase/MadNet/blockchain/executor/tasks/dkg/state" dkgTestUtils "github.com/MadBase/MadNet/blockchain/executor/tasks/dkg/testutils" "github.com/MadBase/MadNet/blockchain/testutils" + "github.com/MadBase/MadNet/blockchain/testutils/cmd" + "math/big" + "testing" "github.com/MadBase/MadNet/logging" "github.com/sirupsen/logrus" @@ -20,8 +19,9 @@ import ( //We test to ensure that everything behaves correctly. func TestMPKSubmission_Group_1_GoodAllValid(t *testing.T) { + workingDir := cmd.CreateTestWorkingFolder() n := 4 - suite := dkgTestUtils.StartFromKeyShareSubmissionPhase(t, n, 0, 100) + suite := dkgTestUtils.StartFromKeyShareSubmissionPhase(t, n, 0, 100, workingDir) defer suite.Eth.Close() accounts := suite.Eth.GetKnownAccounts() ctx := context.Background() @@ -87,8 +87,9 @@ func TestMPKSubmission_Group_1_Bad1(t *testing.T) { // to attempt to submit the mpk. // This should result in an error. // EthDKG restart should be required. + workingDir := cmd.CreateTestWorkingFolder() n := 6 - suite := dkgTestUtils.StartFromKeyShareSubmissionPhase(t, n, 0, 100) + suite := dkgTestUtils.StartFromKeyShareSubmissionPhase(t, n, 0, 100, workingDir) defer suite.Eth.Close() ctx := context.Background() eth := suite.Eth @@ -98,10 +99,9 @@ func TestMPKSubmission_Group_1_Bad1(t *testing.T) { task := suite.MpkSubmissionTasks[0] err := task.Initialize(ctx, logger, eth) assert.Nil(t, err) - eth.Commit() // Advance to gpkj submission phase; note we did *not* submit MPK - testutils.AdvanceTo(t, eth, task.Start+dkgStates[0].PhaseLength) + testutils.AdvanceTo(eth, task.Start+dkgStates[0].PhaseLength) // Do MPK Submission task @@ -112,11 +112,9 @@ func TestMPKSubmission_Group_1_Bad1(t *testing.T) { // We force an error. // This is caused by submitting invalid state information (state is nil). func TestMPKSubmission_Group_1_Bad2(t *testing.T) { - n := 4 - ecdsaPrivateKeys, _ := testutils.InitializePrivateKeysAndAccounts(n) logger := logging.GetLogger("ethereum") logger.SetLevel(logrus.DebugLevel) - eth := testutils.ConnectSimulatorEndpoint(t, ecdsaPrivateKeys, 333*time.Millisecond) + eth := testutils.GetEthereumNetwork(t, false, 4, "", nil) defer eth.Close() acct := eth.GetKnownAccounts()[0] @@ -137,11 +135,9 @@ func TestMPKSubmission_Group_1_Bad2(t *testing.T) { // This is caused by submitting invalid state information by not successfully // completing KeyShareSubmission phase. func TestMPKSubmission_Group_2_Bad4(t *testing.T) { - n := 4 - ecdsaPrivateKeys, _ := testutils.InitializePrivateKeysAndAccounts(n) logger := logging.GetLogger("ethereum") logger.SetLevel(logrus.DebugLevel) - eth := testutils.ConnectSimulatorEndpoint(t, ecdsaPrivateKeys, 333*time.Millisecond) + eth := testutils.GetEthereumNetwork(t, false, 4, "", nil) defer eth.Close() acct := eth.GetKnownAccounts()[0] @@ -159,8 +155,9 @@ func TestMPKSubmission_Group_2_Bad4(t *testing.T) { } func TestMPKSubmission_Group_2_ShouldRetry_returnsFalse(t *testing.T) { + workingDir := cmd.CreateTestWorkingFolder() n := 4 - suite := dkgTestUtils.StartFromKeyShareSubmissionPhase(t, n, 0, 40) + suite := dkgTestUtils.StartFromKeyShareSubmissionPhase(t, n, 0, 40, workingDir) defer suite.Eth.Close() ctx := context.Background() eth := suite.Eth @@ -197,8 +194,9 @@ func TestMPKSubmission_Group_2_ShouldRetry_returnsFalse(t *testing.T) { } func TestMPKSubmission_Group_2_ShouldRetry_returnsTrue(t *testing.T) { + workingDir := cmd.CreateTestWorkingFolder() n := 4 - suite := dkgTestUtils.StartFromKeyShareSubmissionPhase(t, n, 0, 100) + suite := dkgTestUtils.StartFromKeyShareSubmissionPhase(t, n, 0, 100, workingDir) defer suite.Eth.Close() ctx := context.Background() eth := suite.Eth @@ -216,8 +214,9 @@ func TestMPKSubmission_Group_2_ShouldRetry_returnsTrue(t *testing.T) { } func TestMPKSubmission_Group_2_LeaderElection(t *testing.T) { + workingDir := cmd.CreateTestWorkingFolder() n := 4 - suite := dkgTestUtils.StartFromKeyShareSubmissionPhase(t, n, 0, 100) + suite := dkgTestUtils.StartFromKeyShareSubmissionPhase(t, n, 0, 100, workingDir) defer suite.Eth.Close() ctx := context.Background() eth := suite.Eth diff --git a/blockchain/executor/tasks/dkg/register_test.go b/blockchain/executor/tasks/dkg/register_test.go index f9609b1b..a08d2e8b 100644 --- a/blockchain/executor/tasks/dkg/register_test.go +++ b/blockchain/executor/tasks/dkg/register_test.go @@ -4,12 +4,9 @@ package dkg_test import ( "context" - "math/big" "testing" "time" - "github.com/MadBase/MadNet/blockchain/executor/tasks/dkg" - "github.com/MadBase/MadNet/blockchain/executor/tasks/dkg/state" dkgTestUtils "github.com/MadBase/MadNet/blockchain/executor/tasks/dkg/testutils" dkgUtils "github.com/MadBase/MadNet/blockchain/executor/tasks/dkg/utils" "github.com/MadBase/MadNet/blockchain/monitor/events" @@ -22,16 +19,13 @@ import ( ) func TestRegisterTask_Group_1_Task(t *testing.T) { - n := 5 - ecdsaPrivateKeys, _ := testutils.InitializePrivateKeysAndAccounts(n) - //This shouldn't be needed //tr := &objects.TypeRegistry{} //tr.RegisterInstanceType(&RegisterTask{}) logger := logging.GetLogger("ethereum") logger.SetLevel(logrus.DebugLevel) - eth := testutils.ConnectSimulatorEndpoint(t, ecdsaPrivateKeys, 500*time.Millisecond) + eth := testutils.GetEthereumNetwork(t, false, 5, "", nil) defer eth.Close() acct := eth.GetKnownAccounts()[0] @@ -104,474 +98,463 @@ func TestRegisterTask_Group_1_Task(t *testing.T) { assert.Nil(t, err) } -// We attempt valid registration. Everything should succeed. -// This test calls Initialize and DoWork. -func TestRegisterTask_Group_1_Good2(t *testing.T) { - n := 6 - ecdsaPrivateKeys, accounts := testutils.InitializePrivateKeysAndAccounts(n) - - eth := testutils.ConnectSimulatorEndpoint(t, ecdsaPrivateKeys, 333*time.Millisecond) - assert.NotNil(t, eth) - defer eth.Close() - - ctx := context.Background() - - owner := accounts[0] - - // Start EthDKG - ownerOpts, err := eth.GetTransactionOpts(ctx, owner) - assert.Nil(t, err) - - // Shorten ethdkg phase for testing purposes - txn, rcpt, err := dkgTestUtils.SetETHDKGPhaseLength(100, eth, ownerOpts, ctx) - assert.Nil(t, err) - - t.Logf("Updating phase length used %v gas vs %v", rcpt.GasUsed, txn.Cost()) - - // Kick off ethdkg - txn, rcpt, err = dkgTestUtils.InitializeETHDKG(eth, ownerOpts, ctx) - assert.Nil(t, err) - - t.Logf("Updating phase length used %v gas vs %v", rcpt.GasUsed, txn.Cost()) - - event, err := dkgTestUtils.GetETHDKGRegistrationOpened(rcpt.Logs, eth) - assert.Nil(t, err) - assert.NotNil(t, event) - - // get validator addresses - //ctx, cf := context.WithTimeout(context.Background(), 10*time.Second) - //defer cf() - logger := logging.GetLogger("test").WithField("action", "GetValidatorAddressesFromPool") - callOpts, err := eth.GetCallOpts(ctx, eth.GetDefaultAccount()) - assert.Nil(t, err) - validatorAddresses, err := dkgUtils.GetValidatorAddressesFromPool(callOpts, eth, logger.WithField("action", "GetValidatorAddressesFromPool")) - assert.Nil(t, err) - - // Do Register task - tasksVec := make([]*dkg.RegisterTask, n) - dkgStates := make([]*state.DkgState, n) - for idx := 0; idx < n; idx++ { - logger := logging.GetLogger("test").WithField("Validator", accounts[idx].Address.String()) - state, registrationTask, _ := events.UpdateStateOnRegistrationOpened( - accounts[idx], - event.StartBlock.Uint64(), - event.PhaseLength.Uint64(), - event.ConfirmationLength.Uint64(), - event.Nonce.Uint64(), - true, - validatorAddresses, - ) - - dkgStates[idx] = state - tasksVec[idx] = registrationTask - - err = tasksVec[idx].Initialize(ctx, logger, eth) - assert.Nil(t, err) - err = tasksVec[idx].DoWork(ctx, logger, eth) - assert.Nil(t, err) - - eth.Commit() - assert.True(t, tasksVec[idx].Success) - } - - // Check public keys are present and valid; last will be invalid - for idx, acct := range accounts { - callOpts, err := eth.GetCallOpts(context.Background(), acct) - assert.Nil(t, err) - p, err := eth.Contracts().Ethdkg().GetParticipantInternalState(callOpts, acct.Address) - assert.Nil(t, err) - - // check points - publicKey := dkgStates[idx].TransportPublicKey - if (publicKey[0].Cmp(p.PublicKey[0]) != 0) || (publicKey[1].Cmp(p.PublicKey[1]) != 0) { - t.Fatal("Invalid public key") - } - if p.Phase != uint8(state.RegistrationOpen) { - t.Fatal("Invalid participant phase") - } - - } -} - -// We attempt to submit an invalid transport public key (a point not on the curve). -// This should raise an error and not allow that participant to proceed. -func TestRegisterTask_Group_1_Bad1(t *testing.T) { - n := 5 - ecdsaPrivateKeys, accounts := testutils.InitializePrivateKeysAndAccounts(n) - - eth := testutils.ConnectSimulatorEndpoint(t, ecdsaPrivateKeys, 333*time.Millisecond) - assert.NotNil(t, eth) - defer eth.Close() - - ctx := context.Background() - - owner := accounts[0] - ownerOpts, err := eth.GetTransactionOpts(ctx, owner) - assert.Nil(t, err) - - // Shorten ethdkg phase for testing purposes - _, _, err = dkgTestUtils.SetETHDKGPhaseLength(100, eth, ownerOpts, ctx) - assert.Nil(t, err) - - // Start EthDKG - _, rcpt, err := dkgTestUtils.InitializeETHDKG(eth, ownerOpts, ctx) - assert.Nil(t, err) - - event, err := dkgTestUtils.GetETHDKGRegistrationOpened(rcpt.Logs, eth) - assert.Nil(t, err) - assert.NotNil(t, event) - - // get validator addresses - ctx, cf := context.WithTimeout(context.Background(), 10*time.Second) - defer cf() - logger := logging.GetLogger("test").WithField("action", "GetValidatorAddressesFromPool") - callOpts, err := eth.GetCallOpts(ctx, eth.GetDefaultAccount()) - assert.Nil(t, err) - validatorAddresses, err := dkgUtils.GetValidatorAddressesFromPool(callOpts, eth, logger.WithField("action", "GetValidatorAddressesFromPool")) - assert.Nil(t, err) - - // Do Register task - state, registrationTask, _ := events.UpdateStateOnRegistrationOpened( - accounts[0], - event.StartBlock.Uint64(), - event.PhaseLength.Uint64(), - event.ConfirmationLength.Uint64(), - event.Nonce.Uint64(), - true, - validatorAddresses, - ) - - logger = logging.GetLogger("test").WithField("Validator", accounts[0].Address.String()) - - err = registrationTask.Initialize(ctx, logger, eth) - assert.Nil(t, err) - // Mess up private key - state.TransportPrivateKey = big.NewInt(0) - // Mess up public key; this should fail because it is invalid - state.TransportPublicKey = [2]*big.Int{big.NewInt(0), big.NewInt(1)} - err = registrationTask.DoWork(ctx, logger, eth) - assert.NotNil(t, err) -} - -// We attempt to submit an invalid transport public key (submit identity element). -// This should raise an error and not allow that participant to proceed. -func TestRegisterTask_Group_2_Bad2(t *testing.T) { - n := 7 - ecdsaPrivateKeys, accounts := testutils.InitializePrivateKeysAndAccounts(n) - - eth := testutils.ConnectSimulatorEndpoint(t, ecdsaPrivateKeys, 333*time.Millisecond) - assert.NotNil(t, eth) - defer eth.Close() - - ctx := context.Background() - owner := accounts[0] - ownerOpts, err := eth.GetTransactionOpts(ctx, owner) - assert.Nil(t, err) - - // Shorten ethdkg phase for testing purposes - _, _, err = dkgTestUtils.SetETHDKGPhaseLength(100, eth, ownerOpts, ctx) - assert.Nil(t, err) - - // Start EthDKG - _, rcpt, err := dkgTestUtils.InitializeETHDKG(eth, ownerOpts, ctx) - assert.Nil(t, err) - - event, err := dkgTestUtils.GetETHDKGRegistrationOpened(rcpt.Logs, eth) - assert.Nil(t, err) - assert.NotNil(t, event) - - // get validator addresses - ctx, cf := context.WithTimeout(context.Background(), 10*time.Second) - defer cf() - logger := logging.GetLogger("test").WithField("action", "GetValidatorAddressesFromPool") - callOpts, err := eth.GetCallOpts(ctx, eth.GetDefaultAccount()) - assert.Nil(t, err) - validatorAddresses, err := dkgUtils.GetValidatorAddressesFromPool(callOpts, eth, logger.WithField("action", "GetValidatorAddressesFromPool")) - assert.Nil(t, err) - - // Do Register task - state, registrationTask, _ := events.UpdateStateOnRegistrationOpened( - accounts[0], - event.StartBlock.Uint64(), - event.PhaseLength.Uint64(), - event.ConfirmationLength.Uint64(), - event.Nonce.Uint64(), - true, - validatorAddresses, - ) - logger = logging.GetLogger("test").WithField("Validator", accounts[0].Address.String()) - - err = registrationTask.Initialize(ctx, logger, eth) - assert.Nil(t, err) - // Mess up private key - state.TransportPrivateKey = big.NewInt(0) - // Mess up public key; this should fail because it is invalid (the identity element) - state.TransportPublicKey = [2]*big.Int{big.NewInt(0), big.NewInt(0)} - err = registrationTask.DoWork(ctx, logger, eth) - assert.NotNil(t, err) -} - -// The initialization should fail because we dont allow less than 4 validators -func TestRegisterTask_Group_2_Bad4(t *testing.T) { - n := 3 - ecdsaPrivateKeys, _ := testutils.InitializePrivateKeysAndAccounts(n) - - eth := testutils.ConnectSimulatorEndpoint(t, ecdsaPrivateKeys, 333*time.Millisecond) - assert.NotNil(t, eth) - defer eth.Close() - - ctx := context.Background() - - accounts := eth.GetKnownAccounts() - owner := accounts[0] - err := eth.UnlockAccount(owner) - assert.Nil(t, err) - - // Start EthDKG - ownerOpts, err := eth.GetTransactionOpts(ctx, owner) - assert.Nil(t, err) - - // Shorten ethdkg phase for testing purposes - _, _, err = dkgTestUtils.SetETHDKGPhaseLength(100, eth, ownerOpts, ctx) - assert.Nil(t, err) - - // Start EthDKG - _, _, err = dkgTestUtils.InitializeETHDKG(eth, ownerOpts, ctx) - assert.NotNil(t, err) -} - -// We attempt invalid registration. -// Here, we try to register after registration has closed. -// This should raise an error. -func TestRegisterTask_Group_2_Bad5(t *testing.T) { - n := 5 - ecdsaPrivateKeys, accounts := testutils.InitializePrivateKeysAndAccounts(n) - - eth := testutils.ConnectSimulatorEndpoint(t, ecdsaPrivateKeys, 333*time.Millisecond) - assert.NotNil(t, eth) - defer eth.Close() - - ctx := context.Background() - owner := accounts[0] - ownerOpts, err := eth.GetTransactionOpts(ctx, owner) - assert.Nil(t, err) - - // Shorten ethdkg phase for testing purposes - _, _, err = dkgTestUtils.SetETHDKGPhaseLength(100, eth, ownerOpts, ctx) - assert.Nil(t, err) - - // Start EthDKG - _, rcpt, err := dkgTestUtils.InitializeETHDKG(eth, ownerOpts, ctx) - assert.Nil(t, err) - - event, err := dkgTestUtils.GetETHDKGRegistrationOpened(rcpt.Logs, eth) - assert.Nil(t, err) - assert.NotNil(t, event) - - // Do share distribution; afterward, we confirm who is valid and who is not - testutils.AdvanceTo(t, eth, event.StartBlock.Uint64()+event.PhaseLength.Uint64()) - - // get validator addresses - ctx, cf := context.WithTimeout(context.Background(), 10*time.Second) - defer cf() - logger := logging.GetLogger("test").WithField("action", "GetValidatorAddressesFromPool") - callOpts, err := eth.GetCallOpts(ctx, eth.GetDefaultAccount()) - assert.Nil(t, err) - validatorAddresses, err := dkgUtils.GetValidatorAddressesFromPool(callOpts, eth, logger.WithField("action", "GetValidatorAddressesFromPool")) - assert.Nil(t, err) - - // Do Register task - _, registrationTask, _ := events.UpdateStateOnRegistrationOpened( - accounts[0], - event.StartBlock.Uint64(), - event.PhaseLength.Uint64(), - event.ConfirmationLength.Uint64(), - event.Nonce.Uint64(), - true, - validatorAddresses, - ) - logger = logging.GetLogger("test").WithField("Validator", accounts[0].Address.String()) - - err = registrationTask.Initialize(ctx, logger, eth) - assert.Nil(t, err) - err = registrationTask.DoWork(ctx, logger, eth) - assert.NotNil(t, err) -} - -// ShouldRetry() return false because the registration was successful -func TestRegisterTask_Group_3_ShouldRetryFalse(t *testing.T) { - n := 5 - ecdsaPrivateKeys, accounts := testutils.InitializePrivateKeysAndAccounts(n) - - t.Logf("ecdsaPrivateKeys:%v", ecdsaPrivateKeys) - - //This shouldn't be needed - //tr := &objects.TypeRegistry{} - // - //tr.RegisterInstanceType(&RegisterTask{}) - - logger := logging.GetLogger("ethereum") - logger.SetLevel(logrus.DebugLevel) - eth := testutils.ConnectSimulatorEndpoint(t, ecdsaPrivateKeys, 500*time.Millisecond) - defer eth.Close() - - acct := eth.GetKnownAccounts()[0] - - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - - c := eth.Contracts() - - // Check status - callOpts, err := eth.GetCallOpts(ctx, acct) - assert.Nil(t, err) - valid, err := c.ValidatorPool().IsValidator(callOpts, acct.Address) - assert.Nil(t, err, "Failed checking validator status") - assert.True(t, valid) - - // Kick off EthDKG - txnOpts, err := eth.GetTransactionOpts(ctx, eth.GetDefaultAccount()) - assert.Nil(t, err) - - // var ( - // txn *types.Transaction - // rcpt *types.Receipt - // ) - - // Shorten ethdkg phase for testing purposes - txn, rcpt, err := dkgTestUtils.SetETHDKGPhaseLength(4, eth, txnOpts, ctx) - assert.Nil(t, err) - - t.Logf("Updating phase length used %v gas vs %v", rcpt.GasUsed, txn.Cost()) - - // Start EthDKG - _, rcpt, err = dkgTestUtils.InitializeETHDKG(eth, txnOpts, ctx) - assert.Nil(t, err) - assert.NotNil(t, rcpt) - - t.Logf("Kicking off EthDKG used %v gas", rcpt.GasUsed) - t.Logf("registration opens:%v", rcpt.BlockNumber) - - openEvent, err := dkgTestUtils.GetETHDKGRegistrationOpened(rcpt.Logs, eth) - assert.Nil(t, err) - assert.NotNil(t, openEvent) - - // get validator addresses - ctx, cf := context.WithTimeout(context.Background(), 10*time.Second) - defer cf() - validatorAddresses, err := dkgUtils.GetValidatorAddressesFromPool(callOpts, eth, logger.WithField("action", "GetValidatorAddressesFromPool")) - assert.Nil(t, err) - - // Do Register task - _, registrationTask, _ := events.UpdateStateOnRegistrationOpened( - accounts[0], - openEvent.StartBlock.Uint64(), - openEvent.PhaseLength.Uint64(), - openEvent.ConfirmationLength.Uint64(), - openEvent.Nonce.Uint64(), - true, - validatorAddresses, - ) - - log := logger.WithField("TaskID", "foo") - - err = registrationTask.Initialize(ctx, log, eth) - assert.Nil(t, err) - - err = registrationTask.DoWork(ctx, log, eth) - assert.Nil(t, err) - - eth.Commit() - retry := registrationTask.ShouldRetry(ctx, log, eth) - assert.False(t, retry) -} - -// ShouldRetry() return true because the registration was unsuccessful -func TestRegisterTask_Group_3_ShouldRetryTrue(t *testing.T) { - n := 5 - ecdsaPrivateKeys, accounts := testutils.InitializePrivateKeysAndAccounts(n) - - t.Logf("ecdsaPrivateKeys:%v", ecdsaPrivateKeys) - - //This shouldn't be needed - //tr := &objects.TypeRegistry{} - // - //tr.RegisterInstanceType(&RegisterTask{}) - - logger := logging.GetLogger("ethereum") - logger.SetLevel(logrus.DebugLevel) - eth := testutils.ConnectSimulatorEndpoint(t, ecdsaPrivateKeys, 500*time.Millisecond) - defer eth.Close() - - acct := eth.GetKnownAccounts()[0] - - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - - c := eth.Contracts() - - // Check status - callOpts, err := eth.GetCallOpts(ctx, acct) - assert.Nil(t, err) - valid, err := c.ValidatorPool().IsValidator(callOpts, acct.Address) - assert.Nil(t, err, "Failed checking validator status") - assert.True(t, valid) - - // Kick off EthDKG - txnOpts, err := eth.GetTransactionOpts(ctx, eth.GetDefaultAccount()) - assert.Nil(t, err) - - var ( - txn *types.Transaction - rcpt *types.Receipt - ) - - // Shorten ethdkg phase for testing purposes - txn, rcpt, err = dkgTestUtils.SetETHDKGPhaseLength(4, eth, txnOpts, ctx) - assert.Nil(t, err) - - t.Logf("Updating phase length used %v gas vs %v", rcpt.GasUsed, txn.Cost()) - - // Start EthDKG - _, rcpt, err = dkgTestUtils.InitializeETHDKG(eth, txnOpts, ctx) - assert.Nil(t, err) - - t.Logf("Kicking off EthDKG used %v gas", rcpt.GasUsed) - t.Logf("registration opens:%v", rcpt.BlockNumber) - - openEvent, err := dkgTestUtils.GetETHDKGRegistrationOpened(rcpt.Logs, eth) - assert.Nil(t, err) - assert.NotNil(t, openEvent) - - // get validator addresses - ctx, cf := context.WithTimeout(context.Background(), 30*time.Second) - defer cf() - //logger = logging.GetLogger("test").WithField("action", "GetValidatorAddressesFromPool") - //callOpts := eth.GetCallOpts(ctx, eth.GetDefaultAccount()) - validatorAddresses, err := dkgUtils.GetValidatorAddressesFromPool(callOpts, eth, logger.WithField("action", "GetValidatorAddressesFromPool")) - assert.Nil(t, err) - - // Do Register task - state, registrationTask, _ := events.UpdateStateOnRegistrationOpened( - accounts[0], - openEvent.StartBlock.Uint64(), - openEvent.PhaseLength.Uint64(), - openEvent.ConfirmationLength.Uint64(), - openEvent.Nonce.Uint64(), - true, - validatorAddresses, - ) - - log := logger.WithField("TaskID", "foo") - - err = registrationTask.Initialize(ctx, log, eth) - assert.Nil(t, err) - - state.TransportPublicKey[0] = big.NewInt(0) - state.TransportPublicKey[0] = big.NewInt(0) - err = registrationTask.DoWork(ctx, log, eth) - assert.NotNil(t, err) - - retry := registrationTask.ShouldRetry(ctx, log, eth) - assert.True(t, retry) -} +//// We attempt valid registration. Everything should succeed. +//// This test calls Initialize and DoWork. +//func TestRegisterTask_Group_1_Good2(t *testing.T) { +// n := 6 +// _, accounts := testutils.InitializePrivateKeysAndAccounts(n) +// eth := testutils.GetEthereumNetwork(t, false, 6, "", nil, nil) +// assert.NotNil(t, eth) +// defer eth.Close() +// +// ctx := context.Background() +// +// owner := accounts[0] +// +// // Start EthDKG +// ownerOpts, err := eth.GetTransactionOpts(ctx, owner) +// assert.Nil(t, err) +// +// // Shorten ethdkg phase for testing purposes +// txn, rcpt, err := dkgTestUtils.SetETHDKGPhaseLength(100, eth, ownerOpts, ctx) +// assert.Nil(t, err) +// +// t.Logf("Updating phase length used %v gas vs %v", rcpt.GasUsed, txn.Cost()) +// +// // Kick off ethdkg +// txn, rcpt, err = dkgTestUtils.InitializeETHDKG(eth, ownerOpts, ctx) +// assert.Nil(t, err) +// +// t.Logf("Updating phase length used %v gas vs %v", rcpt.GasUsed, txn.Cost()) +// +// event, err := dkgTestUtils.GetETHDKGRegistrationOpened(rcpt.Logs, eth) +// assert.Nil(t, err) +// assert.NotNil(t, event) +// +// // get validator addresses +// //ctx, cf := context.WithTimeout(context.Background(), 10*time.Second) +// //defer cf() +// logger := logging.GetLogger("test").WithField("action", "GetValidatorAddressesFromPool") +// callOpts, err := eth.GetCallOpts(ctx, eth.GetDefaultAccount()) +// assert.Nil(t, err) +// validatorAddresses, err := dkgUtils.GetValidatorAddressesFromPool(callOpts, eth, logger.WithField("action", "GetValidatorAddressesFromPool")) +// assert.Nil(t, err) +// +// // Do Register task +// tasksVec := make([]*dkg.RegisterTask, n) +// dkgStates := make([]*state.DkgState, n) +// for idx := 0; idx < n; idx++ { +// logger := logging.GetLogger("test").WithField("Validator", accounts[idx].Address.String()) +// state, registrationTask, _ := events.UpdateStateOnRegistrationOpened( +// accounts[idx], +// event.StartBlock.Uint64(), +// event.PhaseLength.Uint64(), +// event.ConfirmationLength.Uint64(), +// event.Nonce.Uint64(), +// true, +// validatorAddresses, +// ) +// +// dkgStates[idx] = state +// tasksVec[idx] = registrationTask +// +// err = tasksVec[idx].Initialize(ctx, logger, eth) +// assert.Nil(t, err) +// err = tasksVec[idx].DoWork(ctx, logger, eth) +// assert.Nil(t, err) +// +// assert.True(t, tasksVec[idx].Success) +// } +// +// // Check public keys are present and valid; last will be invalid +// for idx, acct := range accounts { +// callOpts, err := eth.GetCallOpts(context.Background(), acct) +// assert.Nil(t, err) +// p, err := eth.Contracts().Ethdkg().GetParticipantInternalState(callOpts, acct.Address) +// assert.Nil(t, err) +// +// // check points +// publicKey := dkgStates[idx].TransportPublicKey +// if (publicKey[0].Cmp(p.PublicKey[0]) != 0) || (publicKey[1].Cmp(p.PublicKey[1]) != 0) { +// t.Fatal("Invalid public key") +// } +// if p.Phase != uint8(state.RegistrationOpen) { +// t.Fatal("Invalid participant phase") +// } +// +// } +//} +// +//// We attempt to submit an invalid transport public key (a point not on the curve). +//// This should raise an error and not allow that participant to proceed. +//func TestRegisterTask_Group_1_Bad1(t *testing.T) { +// n := 5 +// _, accounts := testutils.InitializePrivateKeysAndAccounts(n) +// eth := testutils.GetEthereumNetwork(t, false, 5, "") +// assert.NotNil(t, eth) +// defer eth.Close() +// +// ctx := context.Background() +// +// owner := accounts[0] +// ownerOpts, err := eth.GetTransactionOpts(ctx, owner) +// assert.Nil(t, err) +// +// // Shorten ethdkg phase for testing purposes +// _, _, err = dkgTestUtils.SetETHDKGPhaseLength(100, eth, ownerOpts, ctx) +// assert.Nil(t, err) +// +// // Start EthDKG +// _, rcpt, err := dkgTestUtils.InitializeETHDKG(eth, ownerOpts, ctx) +// assert.Nil(t, err) +// +// event, err := dkgTestUtils.GetETHDKGRegistrationOpened(rcpt.Logs, eth) +// assert.Nil(t, err) +// assert.NotNil(t, event) +// +// // get validator addresses +// ctx, cf := context.WithTimeout(context.Background(), 10*time.Second) +// defer cf() +// logger := logging.GetLogger("test").WithField("action", "GetValidatorAddressesFromPool") +// callOpts, err := eth.GetCallOpts(ctx, eth.GetDefaultAccount()) +// assert.Nil(t, err) +// validatorAddresses, err := dkgUtils.GetValidatorAddressesFromPool(callOpts, eth, logger.WithField("action", "GetValidatorAddressesFromPool")) +// assert.Nil(t, err) +// +// // Do Register task +// state, registrationTask, _ := events.UpdateStateOnRegistrationOpened( +// accounts[0], +// event.StartBlock.Uint64(), +// event.PhaseLength.Uint64(), +// event.ConfirmationLength.Uint64(), +// event.Nonce.Uint64(), +// true, +// validatorAddresses, +// ) +// +// logger = logging.GetLogger("test").WithField("Validator", accounts[0].Address.String()) +// +// err = registrationTask.Initialize(ctx, logger, eth) +// assert.Nil(t, err) +// // Mess up private key +// state.TransportPrivateKey = big.NewInt(0) +// // Mess up public key; this should fail because it is invalid +// state.TransportPublicKey = [2]*big.Int{big.NewInt(0), big.NewInt(1)} +// err = registrationTask.DoWork(ctx, logger, eth) +// assert.NotNil(t, err) +//} +// +//// We attempt to submit an invalid transport public key (submit identity element). +//// This should raise an error and not allow that participant to proceed. +//func TestRegisterTask_Group_2_Bad2(t *testing.T) { +// n := 7 +// _, accounts := testutils.InitializePrivateKeysAndAccounts(n) +// eth := testutils.GetEthereumNetwork(t, false, 7, "") +// assert.NotNil(t, eth) +// defer eth.Close() +// +// ctx := context.Background() +// owner := accounts[0] +// ownerOpts, err := eth.GetTransactionOpts(ctx, owner) +// assert.Nil(t, err) +// +// // Shorten ethdkg phase for testing purposes +// _, _, err = dkgTestUtils.SetETHDKGPhaseLength(100, eth, ownerOpts, ctx) +// assert.Nil(t, err) +// +// // Start EthDKG +// _, rcpt, err := dkgTestUtils.InitializeETHDKG(eth, ownerOpts, ctx) +// assert.Nil(t, err) +// +// event, err := dkgTestUtils.GetETHDKGRegistrationOpened(rcpt.Logs, eth) +// assert.Nil(t, err) +// assert.NotNil(t, event) +// +// // get validator addresses +// ctx, cf := context.WithTimeout(context.Background(), 10*time.Second) +// defer cf() +// logger := logging.GetLogger("test").WithField("action", "GetValidatorAddressesFromPool") +// callOpts, err := eth.GetCallOpts(ctx, eth.GetDefaultAccount()) +// assert.Nil(t, err) +// validatorAddresses, err := dkgUtils.GetValidatorAddressesFromPool(callOpts, eth, logger.WithField("action", "GetValidatorAddressesFromPool")) +// assert.Nil(t, err) +// +// // Do Register task +// state, registrationTask, _ := events.UpdateStateOnRegistrationOpened( +// accounts[0], +// event.StartBlock.Uint64(), +// event.PhaseLength.Uint64(), +// event.ConfirmationLength.Uint64(), +// event.Nonce.Uint64(), +// true, +// validatorAddresses, +// ) +// logger = logging.GetLogger("test").WithField("Validator", accounts[0].Address.String()) +// +// err = registrationTask.Initialize(ctx, logger, eth) +// assert.Nil(t, err) +// // Mess up private key +// state.TransportPrivateKey = big.NewInt(0) +// // Mess up public key; this should fail because it is invalid (the identity element) +// state.TransportPublicKey = [2]*big.Int{big.NewInt(0), big.NewInt(0)} +// err = registrationTask.DoWork(ctx, logger, eth) +// assert.NotNil(t, err) +//} +// +//// The initialization should fail because we dont allow less than 4 validators +//func TestRegisterTask_Group_2_Bad4(t *testing.T) { +// eth := testutils.GetEthereumNetwork(t, false, 3, "") +// assert.NotNil(t, eth) +// defer eth.Close() +// +// ctx := context.Background() +// +// accounts := eth.GetKnownAccounts() +// owner := accounts[0] +// +// // Start EthDKG +// ownerOpts, err := eth.GetTransactionOpts(ctx, owner) +// assert.Nil(t, err) +// +// // Shorten ethdkg phase for testing purposes +// _, _, err = dkgTestUtils.SetETHDKGPhaseLength(100, eth, ownerOpts, ctx) +// assert.Nil(t, err) +// +// // Start EthDKG +// _, _, err = dkgTestUtils.InitializeETHDKG(eth, ownerOpts, ctx) +// assert.NotNil(t, err) +//} +// +//// We attempt invalid registration. +//// Here, we try to register after registration has closed. +//// This should raise an error. +//func TestRegisterTask_Group_2_Bad5(t *testing.T) { +// n := 5 +// _, accounts := testutils.InitializePrivateKeysAndAccounts(n) +// eth := testutils.GetEthereumNetwork(t, false, 5, "") +// assert.NotNil(t, eth) +// defer eth.Close() +// +// ctx := context.Background() +// owner := accounts[0] +// ownerOpts, err := eth.GetTransactionOpts(ctx, owner) +// assert.Nil(t, err) +// +// // Shorten ethdkg phase for testing purposes +// _, _, err = dkgTestUtils.SetETHDKGPhaseLength(100, eth, ownerOpts, ctx) +// assert.Nil(t, err) +// +// // Start EthDKG +// _, rcpt, err := dkgTestUtils.InitializeETHDKG(eth, ownerOpts, ctx) +// assert.Nil(t, err) +// +// event, err := dkgTestUtils.GetETHDKGRegistrationOpened(rcpt.Logs, eth) +// assert.Nil(t, err) +// assert.NotNil(t, event) +// +// // Do share distribution; afterward, we confirm who is valid and who is not +// testutils.AdvanceTo(eth, event.StartBlock.Uint64()+event.PhaseLength.Uint64()) +// +// // get validator addresses +// ctx, cf := context.WithTimeout(context.Background(), 10*time.Second) +// defer cf() +// logger := logging.GetLogger("test").WithField("action", "GetValidatorAddressesFromPool") +// callOpts, err := eth.GetCallOpts(ctx, eth.GetDefaultAccount()) +// assert.Nil(t, err) +// validatorAddresses, err := dkgUtils.GetValidatorAddressesFromPool(callOpts, eth, logger.WithField("action", "GetValidatorAddressesFromPool")) +// assert.Nil(t, err) +// +// // Do Register task +// _, registrationTask, _ := events.UpdateStateOnRegistrationOpened( +// accounts[0], +// event.StartBlock.Uint64(), +// event.PhaseLength.Uint64(), +// event.ConfirmationLength.Uint64(), +// event.Nonce.Uint64(), +// true, +// validatorAddresses, +// ) +// logger = logging.GetLogger("test").WithField("Validator", accounts[0].Address.String()) +// +// err = registrationTask.Initialize(ctx, logger, eth) +// assert.Nil(t, err) +// err = registrationTask.DoWork(ctx, logger, eth) +// assert.NotNil(t, err) +//} +// +//// ShouldRetry() return false because the registration was successful +//func TestRegisterTask_Group_3_ShouldRetryFalse(t *testing.T) { +// n := 5 +// ecdsaPrivateKeys, accounts := testutils.InitializePrivateKeysAndAccounts(n) +// +// t.Logf("ecdsaPrivateKeys:%v", ecdsaPrivateKeys) +// +// //This shouldn't be needed +// //tr := &objects.TypeRegistry{} +// // +// //tr.RegisterInstanceType(&RegisterTask{}) +// +// logger := logging.GetLogger("ethereum") +// logger.SetLevel(logrus.DebugLevel) +// eth := testutils.GetEthereumNetwork(t, false, 5, "") +// defer eth.Close() +// +// acct := eth.GetKnownAccounts()[0] +// +// ctx, cancel := context.WithCancel(context.Background()) +// defer cancel() +// +// c := eth.Contracts() +// +// // Check status +// callOpts, err := eth.GetCallOpts(ctx, acct) +// assert.Nil(t, err) +// valid, err := c.ValidatorPool().IsValidator(callOpts, acct.Address) +// assert.Nil(t, err, "Failed checking validator status") +// assert.True(t, valid) +// +// // Kick off EthDKG +// txnOpts, err := eth.GetTransactionOpts(ctx, eth.GetDefaultAccount()) +// assert.Nil(t, err) +// +// // var ( +// // txn *types.Transaction +// // rcpt *types.Receipt +// // ) +// +// // Shorten ethdkg phase for testing purposes +// txn, rcpt, err := dkgTestUtils.SetETHDKGPhaseLength(4, eth, txnOpts, ctx) +// assert.Nil(t, err) +// +// t.Logf("Updating phase length used %v gas vs %v", rcpt.GasUsed, txn.Cost()) +// +// // Start EthDKG +// _, rcpt, err = dkgTestUtils.InitializeETHDKG(eth, txnOpts, ctx) +// assert.Nil(t, err) +// assert.NotNil(t, rcpt) +// +// t.Logf("Kicking off EthDKG used %v gas", rcpt.GasUsed) +// t.Logf("registration opens:%v", rcpt.BlockNumber) +// +// openEvent, err := dkgTestUtils.GetETHDKGRegistrationOpened(rcpt.Logs, eth) +// assert.Nil(t, err) +// assert.NotNil(t, openEvent) +// +// // get validator addresses +// ctx, cf := context.WithTimeout(context.Background(), 10*time.Second) +// defer cf() +// validatorAddresses, err := dkgUtils.GetValidatorAddressesFromPool(callOpts, eth, logger.WithField("action", "GetValidatorAddressesFromPool")) +// assert.Nil(t, err) +// +// // Do Register task +// _, registrationTask, _ := events.UpdateStateOnRegistrationOpened( +// accounts[0], +// openEvent.StartBlock.Uint64(), +// openEvent.PhaseLength.Uint64(), +// openEvent.ConfirmationLength.Uint64(), +// openEvent.Nonce.Uint64(), +// true, +// validatorAddresses, +// ) +// +// log := logger.WithField("TaskID", "foo") +// +// err = registrationTask.Initialize(ctx, log, eth) +// assert.Nil(t, err) +// +// err = registrationTask.DoWork(ctx, log, eth) +// assert.Nil(t, err) +// +// retry := registrationTask.ShouldRetry(ctx, log, eth) +// assert.False(t, retry) +//} +// +//// ShouldRetry() return true because the registration was unsuccessful +//func TestRegisterTask_Group_3_ShouldRetryTrue(t *testing.T) { +// n := 5 +// ecdsaPrivateKeys, accounts := testutils.InitializePrivateKeysAndAccounts(n) +// +// t.Logf("ecdsaPrivateKeys:%v", ecdsaPrivateKeys) +// +// //This shouldn't be needed +// //tr := &objects.TypeRegistry{} +// // +// //tr.RegisterInstanceType(&RegisterTask{}) +// +// logger := logging.GetLogger("ethereum") +// logger.SetLevel(logrus.DebugLevel) +// eth := testutils.GetEthereumNetwork(t, false, 5, "") +// defer eth.Close() +// +// acct := eth.GetKnownAccounts()[0] +// +// ctx, cancel := context.WithCancel(context.Background()) +// defer cancel() +// +// c := eth.Contracts() +// +// // Check status +// callOpts, err := eth.GetCallOpts(ctx, acct) +// assert.Nil(t, err) +// valid, err := c.ValidatorPool().IsValidator(callOpts, acct.Address) +// assert.Nil(t, err, "Failed checking validator status") +// assert.True(t, valid) +// +// // Kick off EthDKG +// txnOpts, err := eth.GetTransactionOpts(ctx, eth.GetDefaultAccount()) +// assert.Nil(t, err) +// +// var ( +// txn *types.Transaction +// rcpt *types.Receipt +// ) +// +// // Shorten ethdkg phase for testing purposes +// txn, rcpt, err = dkgTestUtils.SetETHDKGPhaseLength(4, eth, txnOpts, ctx) +// assert.Nil(t, err) +// +// t.Logf("Updating phase length used %v gas vs %v", rcpt.GasUsed, txn.Cost()) +// +// // Start EthDKG +// _, rcpt, err = dkgTestUtils.InitializeETHDKG(eth, txnOpts, ctx) +// assert.Nil(t, err) +// +// t.Logf("Kicking off EthDKG used %v gas", rcpt.GasUsed) +// t.Logf("registration opens:%v", rcpt.BlockNumber) +// +// openEvent, err := dkgTestUtils.GetETHDKGRegistrationOpened(rcpt.Logs, eth) +// assert.Nil(t, err) +// assert.NotNil(t, openEvent) +// +// // get validator addresses +// ctx, cf := context.WithTimeout(context.Background(), 30*time.Second) +// defer cf() +// //logger = logging.GetLogger("test").WithField("action", "GetValidatorAddressesFromPool") +// //callOpts := eth.GetCallOpts(ctx, eth.GetDefaultAccount()) +// validatorAddresses, err := dkgUtils.GetValidatorAddressesFromPool(callOpts, eth, logger.WithField("action", "GetValidatorAddressesFromPool")) +// assert.Nil(t, err) +// +// // Do Register task +// state, registrationTask, _ := events.UpdateStateOnRegistrationOpened( +// accounts[0], +// openEvent.StartBlock.Uint64(), +// openEvent.PhaseLength.Uint64(), +// openEvent.ConfirmationLength.Uint64(), +// openEvent.Nonce.Uint64(), +// true, +// validatorAddresses, +// ) +// +// log := logger.WithField("TaskID", "foo") +// +// err = registrationTask.Initialize(ctx, log, eth) +// assert.Nil(t, err) +// +// state.TransportPublicKey[0] = big.NewInt(0) +// state.TransportPublicKey[0] = big.NewInt(0) +// err = registrationTask.DoWork(ctx, log, eth) +// assert.NotNil(t, err) +// +// retry := registrationTask.ShouldRetry(ctx, log, eth) +// assert.True(t, retry) +//} diff --git a/blockchain/executor/tasks/dkg/share_distribution_test.go b/blockchain/executor/tasks/dkg/share_distribution_test.go index dfe2b4e3..ba293e43 100644 --- a/blockchain/executor/tasks/dkg/share_distribution_test.go +++ b/blockchain/executor/tasks/dkg/share_distribution_test.go @@ -4,24 +4,20 @@ package dkg_test import ( "context" - "math/big" - "testing" - "time" - - "github.com/MadBase/MadNet/blockchain/executor/tasks/dkg" - "github.com/MadBase/MadNet/blockchain/executor/tasks/dkg/state" dkgTestUtils "github.com/MadBase/MadNet/blockchain/executor/tasks/dkg/testutils" - "github.com/MadBase/MadNet/blockchain/testutils" + "github.com/MadBase/MadNet/blockchain/testutils/cmd" "github.com/MadBase/MadNet/logging" "github.com/ethereum/go-ethereum/common" - "github.com/sirupsen/logrus" "github.com/stretchr/testify/assert" + "math/big" + "testing" ) //Here we test the happy path. func TestShareDistribution_Group_1_Good(t *testing.T) { + workingDir := cmd.CreateTestWorkingFolder() n := 5 - suite := dkgTestUtils.StartFromRegistrationOpenPhase(t, n, 0, 100) + suite := dkgTestUtils.StartFromRegistrationOpenPhase(t, n, 0, 100, workingDir) defer suite.Eth.Close() accounts := suite.Eth.GetKnownAccounts() ctx := context.Background() @@ -37,7 +33,6 @@ func TestShareDistribution_Group_1_Good(t *testing.T) { err = shareDistributionTask.DoWork(ctx, logger, suite.Eth) assert.Nil(t, err) - suite.Eth.Commit() assert.True(t, shareDistributionTask.Success) } @@ -47,8 +42,9 @@ func TestShareDistribution_Group_1_Good(t *testing.T) { // One validator attempts to submit invalid commitments (invalid elliptic curve point). // This should result in a failed submission. func TestShareDistribution_Group_1_Bad1(t *testing.T) { + workingDir := cmd.CreateTestWorkingFolder() n := 5 - suite := dkgTestUtils.StartFromRegistrationOpenPhase(t, n, 0, 100) + suite := dkgTestUtils.StartFromRegistrationOpenPhase(t, n, 0, 100, workingDir) defer suite.Eth.Close() accounts := suite.Eth.GetKnownAccounts() ctx := context.Background() @@ -87,8 +83,6 @@ func TestShareDistribution_Group_1_Bad1(t *testing.T) { task.DoWork(ctx, logger, suite.Eth) - suite.Eth.Commit() - // The last task should have failed if idx == badIdx { assert.False(t, task.Success) @@ -111,8 +105,9 @@ func TestShareDistribution_Group_1_Bad1(t *testing.T) { // One validator attempts to submit invalid commitments (identity element). // This should result in a failed submission. func TestShareDistribution_Group_1_Bad2(t *testing.T) { + workingDir := cmd.CreateTestWorkingFolder() n := 4 - suite := dkgTestUtils.StartFromRegistrationOpenPhase(t, n, 0, 100) + suite := dkgTestUtils.StartFromRegistrationOpenPhase(t, n, 0, 100, workingDir) defer suite.Eth.Close() accounts := suite.Eth.GetKnownAccounts() ctx := context.Background() @@ -151,8 +146,6 @@ func TestShareDistribution_Group_1_Bad2(t *testing.T) { task.DoWork(ctx, logger, suite.Eth) - suite.Eth.Commit() - // The last task should have failed if idx == badIdx { assert.False(t, task.Success) @@ -175,8 +168,9 @@ func TestShareDistribution_Group_1_Bad2(t *testing.T) { // One validator attempts to submit invalid commitments (incorrect commitment length) // This should result in a failed submission. func TestShareDistribution_Group_2_Bad4(t *testing.T) { + workingDir := cmd.CreateTestWorkingFolder() n := 5 - suite := dkgTestUtils.StartFromRegistrationOpenPhase(t, n, 0, 100) + suite := dkgTestUtils.StartFromRegistrationOpenPhase(t, n, 0, 100, workingDir) defer suite.Eth.Close() accounts := suite.Eth.GetKnownAccounts() ctx := context.Background() @@ -217,8 +211,6 @@ func TestShareDistribution_Group_2_Bad4(t *testing.T) { task.DoWork(ctx, logger, eth) - eth.Commit() - // The last task should have failed if idx == badCommitmentIdx { assert.False(t, task.Success) @@ -241,8 +233,9 @@ func TestShareDistribution_Group_2_Bad4(t *testing.T) { // One validator attempts to submit invalid commitments (incorrect encrypted shares length) // This should result in a failed submission. func TestShareDistribution_Group_2_Bad5(t *testing.T) { + workingDir := cmd.CreateTestWorkingFolder() n := 6 - suite := dkgTestUtils.StartFromRegistrationOpenPhase(t, n, 0, 100) + suite := dkgTestUtils.StartFromRegistrationOpenPhase(t, n, 0, 100, workingDir) defer suite.Eth.Close() accounts := suite.Eth.GetKnownAccounts() ctx := context.Background() @@ -269,8 +262,6 @@ func TestShareDistribution_Group_2_Bad5(t *testing.T) { task.DoWork(ctx, logger, eth) - eth.Commit() - // The last task should have failed if idx == badShareIdx { assert.False(t, task.Success) @@ -291,12 +282,10 @@ func TestShareDistribution_Group_2_Bad5(t *testing.T) { // We begin by submitting invalid information; // we submit nil state information -func TestShareDistribution_Group_2_Bad6(t *testing.T) { - n := 5 - ecdsaPrivateKeys, _ := testutils.InitializePrivateKeysAndAccounts(n) +/*func TestShareDistribution_Group_2_Bad6(t *testing.T) { logger := logging.GetLogger("ethereum") logger.SetLevel(logrus.DebugLevel) - eth := testutils.ConnectSimulatorEndpoint(t, ecdsaPrivateKeys, 333*time.Millisecond) + eth := testutils.GetEthereumNetwork(t, false, 5, "") defer eth.Close() acct := eth.GetKnownAccounts()[0] @@ -316,11 +305,9 @@ func TestShareDistribution_Group_2_Bad6(t *testing.T) { // We test to ensure that everything behaves correctly. // We submit invalid state information (again). func TestShareDistribution_Group_3_Bad7(t *testing.T) { - n := 4 - ecdsaPrivateKeys, _ := testutils.InitializePrivateKeysAndAccounts(n) logger := logging.GetLogger("ethereum") logger.SetLevel(logrus.DebugLevel) - eth := testutils.ConnectSimulatorEndpoint(t, ecdsaPrivateKeys, 333*time.Millisecond) + eth := testutils.GetEthereumNetwork(t, false, 4, "") defer eth.Close() acct := eth.GetKnownAccounts()[0] @@ -339,9 +326,12 @@ func TestShareDistribution_Group_3_Bad7(t *testing.T) { } } +*/ func TestShareDistribution_Group_3_ShouldRetryTrue(t *testing.T) { + + workingDir := cmd.CreateTestWorkingFolder() n := 5 - suite := dkgTestUtils.StartFromRegistrationOpenPhase(t, n, 0, 100) + suite := dkgTestUtils.StartFromRegistrationOpenPhase(t, n, 0, 100, workingDir) defer suite.Eth.Close() accounts := suite.Eth.GetKnownAccounts() ctx := context.Background() @@ -362,8 +352,9 @@ func TestShareDistribution_Group_3_ShouldRetryTrue(t *testing.T) { } func TestShareDistribution_Group_3_ShouldRetryFalse(t *testing.T) { + workingDir := cmd.CreateTestWorkingFolder() n := 5 - suite := dkgTestUtils.StartFromRegistrationOpenPhase(t, n, 0, 100) + suite := dkgTestUtils.StartFromRegistrationOpenPhase(t, n, 0, 100, workingDir) defer suite.Eth.Close() accounts := suite.Eth.GetKnownAccounts() ctx := context.Background() @@ -379,7 +370,6 @@ func TestShareDistribution_Group_3_ShouldRetryFalse(t *testing.T) { err = task.DoWork(ctx, logger, suite.Eth) assert.Nil(t, err) - suite.Eth.Commit() assert.True(t, task.Success) shouldRetry := task.ShouldRetry(ctx, logger, suite.Eth) diff --git a/blockchain/executor/tasks/dkg/state/validate_test.go b/blockchain/executor/tasks/dkg/state/validate_test.go index 77f7faf2..aa9711d7 100644 --- a/blockchain/executor/tasks/dkg/state/validate_test.go +++ b/blockchain/executor/tasks/dkg/state/validate_test.go @@ -174,8 +174,8 @@ func TestMath_VerifyDistributedSharesBad3(t *testing.T) { threshold := state.ThresholdForUserCount(n) // Setup keys - ecdsaPrivKeys := testutils.SetupPrivateKeys(n) - accountsArray := testutils.SetupAccounts(ecdsaPrivKeys) + ecdsaPrivKeys := testutils.GeneratePrivateKeys(n) + accountsArray := testutils.GenerateAccounts(ecdsaPrivKeys) // Validator Setup dkgIdx := 0 diff --git a/blockchain/executor/tasks/dkg/testutils/advance_phases.go b/blockchain/executor/tasks/dkg/testutils/advance_phases.go index 86423e27..d0b835c1 100644 --- a/blockchain/executor/tasks/dkg/testutils/advance_phases.go +++ b/blockchain/executor/tasks/dkg/testutils/advance_phases.go @@ -6,24 +6,24 @@ import ( "context" "crypto/ecdsa" "errors" - "math/big" - "strings" - "testing" - "time" - "github.com/MadBase/MadNet/blockchain/executor/tasks/dkg" "github.com/MadBase/MadNet/blockchain/executor/tasks/dkg/state" "github.com/MadBase/MadNet/blockchain/executor/tasks/dkg/utils" "github.com/MadBase/MadNet/blockchain/monitor/events" - "github.com/MadBase/MadNet/blockchain/testutils" + testutils "github.com/MadBase/MadNet/blockchain/testutils" + "github.com/MadBase/MadNet/blockchain/testutils/cmd" "github.com/MadBase/MadNet/blockchain/transaction" "github.com/MadBase/MadNet/bridge/bindings" + "github.com/MadBase/MadNet/crypto/bn256" + "github.com/MadBase/MadNet/crypto/bn256/cloudflare" + "github.com/ethereum/go-ethereum/accounts" "github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/core/types" - - "github.com/MadBase/MadNet/crypto/bn256" - "github.com/MadBase/MadNet/crypto/bn256/cloudflare" + "log" + "math/big" + "strings" + "testing" "github.com/MadBase/MadNet/blockchain/ethereum" "github.com/MadBase/MadNet/logging" @@ -50,6 +50,7 @@ type TestSuite struct { } func SetETHDKGPhaseLength(length uint16, eth ethereum.Network, callOpts *bind.TransactOpts, ctx context.Context) (*types.Transaction, *types.Receipt, error) { + // Shorten ethdkg phase for testing purposes ethdkgABI, err := abi.JSON(strings.NewReader(bindings.ETHDKGMetaData.ABI)) if err != nil { @@ -70,14 +71,16 @@ func SetETHDKGPhaseLength(length uint16, eth ethereum.Network, callOpts *bind.Tr } watcher := transaction.WatcherFromNetwork(eth) - rcpt, err := watcher.SubscribeAndWait(ctx, txn) + c, err := watcher.Subscribe(ctx, txn) + testutils.MineBlocks(eth, 12) + rcpt, err := watcher.Wait(ctx, c) + if err != nil { return nil, nil, err } if rcpt == nil { return nil, nil, errors.New("non existent receipt for tx ContractFactory.CallAny(ethdkg, setPhaseLength(...))") } - return txn, rcpt, nil } @@ -102,7 +105,10 @@ func InitializeETHDKG(eth ethereum.Network, callOpts *bind.TransactOpts, ctx con } watcher := transaction.WatcherFromNetwork(eth) - rcpt, err := watcher.SubscribeAndWait(ctx, txn) + c, err := watcher.Subscribe(ctx, txn) + testutils.MineBlocks(eth, 12) + rcpt, err := watcher.Wait(ctx, c) + if err != nil { return nil, nil, err } @@ -113,19 +119,42 @@ func InitializeETHDKG(eth ethereum.Network, callOpts *bind.TransactOpts, ctx con return txn, rcpt, nil } -func StartFromRegistrationOpenPhase(t *testing.T, n int, unregisteredValidators int, phaseLength uint16) *TestSuite { - ecdsaPrivateKeys, accounts := testutils.InitializePrivateKeysAndAccounts(n) +func StartFromRegistrationOpenPhase(t *testing.T, n int, unregisteredValidators int, phaseLength uint16, workingDir string) *TestSuite { + //ecdsaPrivateKeys, accountList := testutils.InitializePrivateKeysAndAccounts(n) + log.Printf("********** 0 - Testing with %d validators", n) - eth := testutils.ConnectSimulatorEndpoint(t, ecdsaPrivateKeys, 1000*time.Millisecond) + accountMap := testutils.InitializePrivateKeysAndAccountsMap(n) + + log.Printf("*** running init") + err := cmd.RunInit(workingDir, n, accountMap) + assert.Nil(t, err) + + //eth := testutils.GetEthereumNetwork(t, ecdsaPrivateKeys, 1000*time.Millisecond) + //eth := testutils.GetEthereumNetwork(t, false, n, workingDir) + eth := testutils.GetEthereumNetwork(t, false, n, workingDir, accountMap) assert.NotNil(t, eth) + log.Printf("********** 8 - Got ETH network") + log.Printf("********** 9 - eth default account (owner) address: %s", eth.GetDefaultAccount().Address.String()) ctx := context.Background() - owner := accounts[0] + var owner = eth.GetDefaultAccount() + + accountList := make([]accounts.Account, 0) + ecdsaPrivateKeys := make([]*ecdsa.PrivateKey, 0) + for a, k := range accountMap { + accountList = append(accountList, a) + ecdsaPrivateKeys = append(ecdsaPrivateKeys, k) + } // Start EthDKG ownerOpts, err := eth.GetTransactionOpts(ctx, owner) assert.Nil(t, err) + log.Printf("********** 10 - Owner opts %v", ownerOpts) + log.Printf("********** 11 - at this point account map looks like this") + for v := range accountMap { + log.Printf(" %s", v.Address.String()) + } // Shorten ethdkg phase for testing purposes _, _, err = SetETHDKGPhaseLength(phaseLength, eth, ownerOpts, ctx) assert.Nil(t, err) @@ -148,19 +177,20 @@ func StartFromRegistrationOpenPhase(t *testing.T, n int, unregisteredValidators assert.Nil(t, err) assert.Equal(t, uint8(state.RegistrationOpen), phase) - valCount, err := eth.Contracts().ValidatorPool().GetValidatorsCount(callOpts) - assert.Nil(t, err) - assert.Equal(t, uint64(n), valCount.Uint64()) + // TODO - remove owner + //valCount, err := eth.Contracts().ValidatorPool().GetValidatorsCount(callOpts) + //assert.Nil(t, err) + //assert.Equal(t, uint64(n), valCount.Uint64()) // Do Register task regTasks := make([]*dkg.RegisterTask, n) dispMissingRegTasks := make([]*dkg.DisputeMissingRegistrationTask, n) dkgStates := make([]*state.DkgState, n) for idx := 0; idx < n; idx++ { - logger := logging.GetLogger("test").WithField("Validator", accounts[idx].Address.String()) + logger := logging.GetLogger("test").WithField("Validator", accountList[idx].Address.String()) // Set Registration success to true state, regTask, dispMissingRegTask := events.UpdateStateOnRegistrationOpened( - accounts[idx], + accountList[idx], event.StartBlock.Uint64(), event.PhaseLength.Uint64(), event.ConfirmationLength.Uint64(), @@ -186,8 +216,6 @@ func StartFromRegistrationOpenPhase(t *testing.T, n int, unregisteredValidators err = regTasks[idx].DoWork(ctx, logger, eth) assert.Nil(t, err) - - eth.Commit() assert.True(t, regTasks[idx].Success) } @@ -221,10 +249,10 @@ func StartFromRegistrationOpenPhase(t *testing.T, n int, unregisteredValidators } // skip all the way to ShareDistribution phase - testutils.AdvanceTo(t, eth, shareDistributionTasks[0].Start) + testutils.AdvanceTo(eth, shareDistributionTasks[0].Start) } else { // this means some validators did not register, and the next phase is DisputeMissingRegistration - testutils.AdvanceTo(t, eth, dkgStates[0].PhaseStart+dkgStates[0].PhaseLength) + testutils.AdvanceTo(eth, dkgStates[0].PhaseStart+dkgStates[0].PhaseLength) } return &TestSuite{ @@ -239,8 +267,8 @@ func StartFromRegistrationOpenPhase(t *testing.T, n int, unregisteredValidators } } -func StartFromShareDistributionPhase(t *testing.T, n int, undistributedSharesIdx []int, badSharesIdx []int, phaseLength uint16) *TestSuite { - suite := StartFromRegistrationOpenPhase(t, n, 0, phaseLength) +func StartFromShareDistributionPhase(t *testing.T, n int, undistributedSharesIdx []int, badSharesIdx []int, phaseLength uint16, workingDir string) *TestSuite { + suite := StartFromRegistrationOpenPhase(t, n, 0, phaseLength, workingDir) ctx := context.Background() logger := logging.GetLogger("test").WithField("Validator", "") @@ -286,8 +314,6 @@ func StartFromShareDistributionPhase(t *testing.T, n int, undistributedSharesIdx err = shareDistTask.DoWork(ctx, logger, suite.Eth) assert.Nil(t, err) - - suite.Eth.Commit() assert.True(t, shareDistTask.Success) // event @@ -330,22 +356,22 @@ func StartFromShareDistributionPhase(t *testing.T, n int, undistributedSharesIdx suite.DisputeMissingKeyshareTasks = disputeMissingKeySharesTasks // skip all the way to DisputeShareDistribution phase - testutils.AdvanceTo(t, suite.Eth, dispShareDistStartBlock) + testutils.AdvanceTo(suite.Eth, dispShareDistStartBlock) } else { // this means some validators did not distribute shares, and the next phase is DisputeMissingShareDistribution - testutils.AdvanceTo(t, suite.Eth, suite.DKGStates[0].PhaseStart+suite.DKGStates[0].PhaseLength) + testutils.AdvanceTo(suite.Eth, suite.DKGStates[0].PhaseStart+suite.DKGStates[0].PhaseLength) } return suite } -func StartFromKeyShareSubmissionPhase(t *testing.T, n int, undistributedShares int, phaseLength uint16) *TestSuite { - suite := StartFromShareDistributionPhase(t, n, []int{}, []int{}, phaseLength) +func StartFromKeyShareSubmissionPhase(t *testing.T, n int, undistributedShares int, phaseLength uint16, workingDir string) *TestSuite { + suite := StartFromShareDistributionPhase(t, n, []int{}, []int{}, phaseLength, workingDir) ctx := context.Background() logger := logging.GetLogger("test").WithField("Validator", "") keyshareSubmissionStartBlock := suite.KeyshareSubmissionTasks[0].Start - testutils.AdvanceTo(t, suite.Eth, keyshareSubmissionStartBlock) + testutils.AdvanceTo(suite.Eth, keyshareSubmissionStartBlock) // Do key share submission task for idx := 0; idx < n; idx++ { @@ -362,8 +388,6 @@ func StartFromKeyShareSubmissionPhase(t *testing.T, n int, undistributedShares i err = keyshareSubmissionTask.DoWork(ctx, logger, suite.Eth) assert.Nil(t, err) - - suite.Eth.Commit() assert.True(t, keyshareSubmissionTask.Success) // event @@ -396,10 +420,10 @@ func StartFromKeyShareSubmissionPhase(t *testing.T, n int, undistributedShares i } // skip all the way to MPKSubmission phase - testutils.AdvanceTo(t, suite.Eth, mpkSubmissionTaskStart) + testutils.AdvanceTo(suite.Eth, mpkSubmissionTaskStart) } else { // this means some validators did not submit key shares, and the next phase is DisputeMissingKeyShares - testutils.AdvanceTo(t, suite.Eth, suite.DKGStates[0].PhaseStart+suite.DKGStates[0].PhaseLength) + testutils.AdvanceTo(suite.Eth, suite.DKGStates[0].PhaseStart+suite.DKGStates[0].PhaseLength) } suite.MpkSubmissionTasks = mpkSubmissionTasks @@ -407,8 +431,8 @@ func StartFromKeyShareSubmissionPhase(t *testing.T, n int, undistributedShares i return suite } -func StartFromMPKSubmissionPhase(t *testing.T, n int, phaseLength uint16) *TestSuite { - suite := StartFromKeyShareSubmissionPhase(t, n, 0, phaseLength) +func StartFromMPKSubmissionPhase(t *testing.T, n int, phaseLength uint16, workingDir string) *TestSuite { + suite := StartFromKeyShareSubmissionPhase(t, n, 0, phaseLength, workingDir) ctx := context.Background() logger := logging.GetLogger("test").WithField("Validator", "") dkgStates := suite.DKGStates @@ -427,8 +451,6 @@ func StartFromMPKSubmissionPhase(t *testing.T, n int, phaseLength uint16) *TestS } } - eth.Commit() - height, err := suite.Eth.GetCurrentHeight(ctx) assert.Nil(t, err) @@ -452,8 +474,8 @@ func StartFromMPKSubmissionPhase(t *testing.T, n int, phaseLength uint16) *TestS return suite } -func StartFromGPKjPhase(t *testing.T, n int, undistributedGPKjIdx []int, badGPKjIdx []int, phaseLength uint16) *TestSuite { - suite := StartFromMPKSubmissionPhase(t, n, phaseLength) +func StartFromGPKjPhase(t *testing.T, n int, undistributedGPKjIdx []int, badGPKjIdx []int, phaseLength uint16, workingDir string) *TestSuite { + suite := StartFromMPKSubmissionPhase(t, n, phaseLength, workingDir) ctx := context.Background() logger := logging.GetLogger("test").WithField("Validator", "") @@ -495,8 +517,6 @@ func StartFromGPKjPhase(t *testing.T, n int, undistributedGPKjIdx []int, badGPKj err = gpkjSubTask.DoWork(ctx, logger, suite.Eth) assert.Nil(t, err) - - suite.Eth.Commit() assert.True(t, gpkjSubTask.Success) // event @@ -533,20 +553,20 @@ func StartFromGPKjPhase(t *testing.T, n int, undistributedGPKjIdx []int, badGPKj suite.CompletionTasks = completionTasks // skip all the way to DisputeGPKj phase - testutils.AdvanceTo(t, suite.Eth, dispGPKjStartBlock) + testutils.AdvanceTo(suite.Eth, dispGPKjStartBlock) } else { // this means some validators did not submit their GPKjs, and the next phase is DisputeMissingGPKj - testutils.AdvanceTo(t, suite.Eth, suite.DKGStates[0].PhaseStart+suite.DKGStates[0].PhaseLength) + testutils.AdvanceTo(suite.Eth, suite.DKGStates[0].PhaseStart+suite.DKGStates[0].PhaseLength) } return suite } -func StartFromCompletion(t *testing.T, n int, phaseLength uint16) *TestSuite { - suite := StartFromGPKjPhase(t, n, []int{}, []int{}, phaseLength) +func StartFromCompletion(t *testing.T, n int, phaseLength uint16, workingDir string) *TestSuite { + suite := StartFromGPKjPhase(t, n, []int{}, []int{}, phaseLength, workingDir) // move to Completion phase - testutils.AdvanceTo(t, suite.Eth, suite.CompletionTasks[0].Start+suite.DKGStates[0].ConfirmationLength) + testutils.AdvanceTo(suite.Eth, suite.CompletionTasks[0].Start+suite.DKGStates[0].ConfirmationLength) return suite } diff --git a/blockchain/executor/tasks/dkg/testutils/setup.go b/blockchain/executor/tasks/dkg/testutils/setup.go index 6c5329ec..eb9695c7 100644 --- a/blockchain/executor/tasks/dkg/testutils/setup.go +++ b/blockchain/executor/tasks/dkg/testutils/setup.go @@ -66,8 +66,8 @@ func InitializeNewNonDetDkgStateInfo(n int) ([]*state.DkgState, []*ecdsa.Private func InitializeNewDkgStateInfo(n int, deterministicShares bool) ([]*state.DkgState, []*ecdsa.PrivateKey) { // Get private keys for validators - privKeys := testutils.SetupPrivateKeys(n) - accountsArray := testutils.SetupAccounts(privKeys) + privKeys := testutils.GeneratePrivateKeys(n) + accountsArray := testutils.GenerateAccounts(privKeys) dkgStates := []*state.DkgState{} threshold := crypto.CalcThreshold(n) diff --git a/blockchain/testutils/cmd/deploy.go b/blockchain/testutils/cmd/deploy.go new file mode 100644 index 00000000..dfa9b732 --- /dev/null +++ b/blockchain/testutils/cmd/deploy.go @@ -0,0 +1,83 @@ +package cmd + +import ( + "crypto/ecdsa" + "github.com/ethereum/go-ethereum/accounts" + "os" + "path/filepath" + "strings" +) + +func RunDeploy(workingDir string, accountPrivateKeyMap map[accounts.Account]*ecdsa.PrivateKey) (string, error) { + + bridgeDir := GetBridgePath() + _, _, err := executeCommand(bridgeDir, "npx", "hardhat --network dev setHardhatIntervalMining --enable-auto-mine") + if err != nil { + return "", err + } + + _, output, err := executeCommand(bridgeDir, "npx", "hardhat --network dev --show-stack-traces deployContracts --input-folder", filepath.Join(workingDir, "scripts", "generated")) + if err != nil { + return "", err + } + firstLogLine := strings.Split(string(output), "\n")[0] + addressLine := strings.Split(firstLogLine, ":") + factoryAddress := strings.TrimSpace(addressLine[len(addressLine)-1]) + + err = ReplaceOwnerRegistryAddress(workingDir, factoryAddress) + if err != nil { + return "", err + } + err = ReplaceValidatorsRegistryAddress(workingDir, factoryAddress) + if err != nil { + return "", err + } + + // Replace filename + + _, _, err = executeCommand(bridgeDir, "npx", "hardhat --network dev fundValidators --config-path", filepath.Join(workingDir, "scripts", "generated", "config")) + if err != nil { + return "", err + } + + _, isSet := os.LookupEnv("SKIP_REGISTRATION") + if isSet { + return "", nil + } + + _, _, err = executeCommand(bridgeDir, "npx", "hardhat --network dev setHardhatIntervalMining --interval 100") + if err != nil { + return "", err + } + + var validatorsAddressList []string + for k := range accountPrivateKeyMap { + if k.Address.String() != "0x546F99F244b7B58B855330AE0E2BC1b30b41302F" { + validatorsAddressList = append(validatorsAddressList, k.Address.String()) + } + } + + err = RunRegister(factoryAddress, validatorsAddressList) + if err != nil { + return "", err + } + + _, _, err = executeCommand(bridgeDir, "npx", "hardhat --network dev setMinEthereumBlocksPerSnapshot --block-num 10 --factory-address", factoryAddress) + if err != nil { + return "", err + } + + _, _, err = executeCommand(bridgeDir, "npx", "hardhat --network dev setHardhatIntervalMining") + if err != nil { + return "", err + } + + //generatedValidatorConfigFiles := filepath.Join(workingDir, "scripts", "generated", "config") + //files, _ := ioutil.ReadDir(generatedValidatorConfigFiles) + //err = RunValidator(workingDir, len(files)) + //if err != nil { + // return "", err + //} + + return factoryAddress, nil +} diff --git a/blockchain/testutils/cmd/executor.go b/blockchain/testutils/cmd/executor.go new file mode 100644 index 00000000..b749aeb6 --- /dev/null +++ b/blockchain/testutils/cmd/executor.go @@ -0,0 +1,280 @@ +package cmd + +import ( + "crypto/rand" + "encoding/hex" + "fmt" + "io" + "io/ioutil" + "log" + "os" + "os/exec" + "path/filepath" + "regexp" + "strconv" + "strings" +) + +// TODO - double check github action will pick this up + +// SetCommandStdOut If ENABLE_SCRIPT_LOG env variable is set as 'true' the command will show scripts logs +func SetCommandStdOut(cmd *exec.Cmd) { + + flagValue, found := os.LookupEnv("ENABLE_SCRIPT_LOG") + enabled, err := strconv.ParseBool(flagValue) + + if err == nil && found && enabled { + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + } else { + cmd.Stdout = io.Discard + cmd.Stderr = io.Discard + } +} + +func executeCommand(dir, command string, args ...string) (*exec.Cmd, []byte, error) { + cmdArgs := strings.Split(strings.Join(args, " "), " ") + + cmd := exec.Command(command, cmdArgs...) + cmd.Dir = dir + cmd.Stderr = os.Stderr + output, err := cmd.Output() + + if err != nil { + log.Printf("Error executing command: %v %v in dir: %v. %v", command, cmdArgs, dir, string(output)) + return &exec.Cmd{}, output, err + } + log.Printf("Command Executed: %v %s in dir: %v. \n%s\n", command, cmdArgs, dir, string(output)) + + return cmd, output, err +} + +func runCommand(dir, command string, args ...string) (*exec.Cmd, []byte, error) { + cmdArgs := strings.Split(strings.Join(args, " "), " ") + + cmd := exec.Command(command, cmdArgs...) + cmd.Dir = dir + err := cmd.Start() + if err != nil { + fmt.Printf("Error executing command: %v %v in dir: %v. %v", command, cmdArgs, dir, err) + return &exec.Cmd{}, nil, err + } + + return cmd, nil, err +} + +// TODO - make it wait() +// CreateTempFolder creates a test working folder in the OS temporary resources folder +func CreateTempFolder() (string, error) { + file, err := ioutil.TempDir("", "unittest") + if err != nil { + return "", err + } + + return file, nil +} + +// TODO - make it wait() +func CopyFileToFolder(src, dst string) (int64, error) { + sourceFileStat, err := os.Stat(src) + if err != nil { + return 0, err + } + + if !sourceFileStat.Mode().IsRegular() { + return 0, fmt.Errorf("%s is not a regular file", src) + } + + source, err := os.Open(src) + if err != nil { + return 0, err + } + defer source.Close() + + _, err = os.Create(dst) + destination, err := os.Create(dst) + if err != nil { + return 0, err + } + defer destination.Close() + nBytes, err := io.Copy(destination, source) + return nBytes, err +} + +// GetProjectRootPath returns the project root path +func GetProjectRootPath() string { + + rootPath := []string{string(os.PathSeparator)} + + cmd := exec.Command("go", "list", "-m", "-f", "'{{.Dir}}'", "github.com/MadBase/MadNet") + stdout, err := cmd.Output() + if err != nil { + log.Printf("Error getting project root path: %v", err) + return "" + } + path := string(stdout) + path = strings.ReplaceAll(path, "'", "") + path = strings.ReplaceAll(path, "\n", "") + + pathNodes := strings.Split(path, string(os.PathSeparator)) + for _, pathNode := range pathNodes { + rootPath = append(rootPath, pathNode) + } + + return filepath.Join(rootPath...) +} + +// GetBridgePath return the bridge folder path +func GetBridgePath() string { + rootPath := GetProjectRootPath() + bridgePath := filepath.Join(rootPath, "bridge") + + return bridgePath +} + +//RandomHex hexdump -n 16 -e '4/4 "%08X" 1 "\n"' /dev/urandom +func RandomHex(n int) (string, error) { + bytes := make([]byte, n) + if _, err := rand.Read(bytes); err != nil { + return "", err + } + + return strings.ToUpper(hex.EncodeToString(bytes)), nil +} + +func ReplaceConfigurationFile(workingDir, address, privateKey string, listeningPort, p2pPort, discoveryPort, localStatePort, index int) error { + baseConfigFile, err := os.ReadFile(filepath.Join(workingDir, "scripts", "base-files", "baseConfig")) + if err != nil { + log.Fatalf("Error reading base configuration file - %v", err) + return err + } + fileContent := string(baseConfigFile) + validatorFileName := "validator" + strconv.Itoa(index) + + regex := regexp.MustCompile(`defaultAccount = .*`) + result := regex.ReplaceAllString(fileContent, "defaultAccount = \""+address+"\"") + regex = regexp.MustCompile(`rewardAccount = .*`) + result = regex.ReplaceAllString(result, "rewardAccount = \""+address+"\"") + regex = regexp.MustCompile(`listeningAddress = .*`) + result = regex.ReplaceAllString(result, "listeningAddress = \"0.0.0.0:"+strconv.Itoa(listeningPort)+"\"") + regex = regexp.MustCompile(`p2pListeningAddress = .*`) + result = regex.ReplaceAllString(result, "p2pListeningAddress = \"0.0.0.0:"+strconv.Itoa(p2pPort)+"\"") + regex = regexp.MustCompile(`discoveryListeningAddress = .*`) + result = regex.ReplaceAllString(result, "discoveryListeningAddress = \"0.0.0.0:"+strconv.Itoa(discoveryPort)+"\"") + regex = regexp.MustCompile(`localStateListeningAddress = .*`) + result = regex.ReplaceAllString(result, "localStateListeningAddress = \"0.0.0.0:"+strconv.Itoa(localStatePort)+"\"") + regex = regexp.MustCompile(`passcodes = .*`) + result = regex.ReplaceAllString(result, "passcodes = \""+filepath.Join("scripts", "generated", "keystores", "passcodes.txt")+"\"") // TODO - check file path root project or working dir + regex = regexp.MustCompile(`keystore = .*`) + result = regex.ReplaceAllString(result, "keystore = \""+filepath.Join("scripts", "generated", "keystores", "keys")+"\"") + regex = regexp.MustCompile(`stateDB = .*`) + result = regex.ReplaceAllString(result, "stateDB = \""+filepath.Join("scripts", "generated", "stateDBs", validatorFileName)+"\"") + regex = regexp.MustCompile(`monitorDB = .*`) + result = regex.ReplaceAllString(result, "monitorDB = \""+filepath.Join("scripts", "generated", "monitorDBs", validatorFileName)+"\"") + regex = regexp.MustCompile(`privateKey = .*`) + result = regex.ReplaceAllString(result, "privateKey = \""+privateKey+"\"") + + f, err := os.Create(filepath.Join(workingDir, "scripts", "generated", "config", validatorFileName+".toml")) + if err != nil { + log.Fatalf("Error creating validator configuration file - %v", err) + return err + } + _, err = fmt.Fprintf(f, "%s", result) + if err != nil { + log.Fatalf("Error writing on validator configuration file - %v", err) + return err + } + defer f.Close() + return nil +} + +func ReplaceGenesisBalance(workingDir string) error { + genesisFilePath := filepath.Join(workingDir, "scripts", "base-files", "genesis.json") + genesisConfigFile, err := os.ReadFile(genesisFilePath) + if err != nil { + log.Fatalf("Error reading base configuration file - %v", err) + return err + } + fileContent := string(genesisConfigFile) + regex := regexp.MustCompile(`balance.*`) + result := regex.ReplaceAllString(fileContent, "balance\": \"10000000000000000000000\" }") + + f, err := os.Create(filepath.Join(workingDir, "scripts", "generated", "genesis.json")) + if err != nil { + log.Fatalf("Error creating modified genesis.json file - %v", err) + return err + } + _, err = fmt.Fprintf(f, "%s", result) + if err != nil { + log.Fatalf("Error writing on new genesis.json file - %v", err) + return err + } + defer f.Close() + return nil +} + +func ReplaceOwnerRegistryAddress(workingDir, factoryAddress string) error { + ownerFilePath := filepath.Join(workingDir, "scripts", "generated", "owner.toml") + ownerFile, err := os.ReadFile(ownerFilePath) + if err != nil { + log.Fatalf("Error reading base configuration file - %v", err) + return err + } + fileContent := string(ownerFile) + regex := regexp.MustCompile(`registryAddress = .*`) + result := regex.ReplaceAllString(fileContent, "registryAddress = \""+factoryAddress+"\"") + + f, err := os.Create(ownerFilePath) + if err != nil { + log.Fatalf("Error creating file %v - %v", ownerFilePath, err) + return err + } + _, err = fmt.Fprintf(f, "%s", result) + if err != nil { + log.Fatalf("Error writing on new genesis.json file - %v", err) + return err + } + defer f.Close() + return nil +} + +func ReplaceValidatorsRegistryAddress(workingDir, factoryAddress string) error { + filePath := filepath.Join(workingDir, "scripts", "generated", "config") + files, err := ioutil.ReadDir(filePath) + if err != nil { + return err + } + + for _, file := range files { + fileBytes, err := os.ReadFile(filepath.Join(filePath, file.Name())) + if err != nil { + log.Fatalf("Error reading base configuration file - %v", err) + return err + } + fileContent := string(fileBytes) + regex := regexp.MustCompile(`registryAddress = .*`) + result := regex.ReplaceAllString(fileContent, "registryAddress = \""+factoryAddress+"\"") + + f, err := os.Create(filepath.Join(filePath, file.Name())) + if err != nil { + log.Fatalf("Error creating file %v - %v", filePath, err) + return err + } + _, err = fmt.Fprintf(f, "%s", result) + if err != nil { + log.Fatalf("Error writing on new genesis.json file - %v", err) + return err + } + defer f.Close() + } + + return nil +} + +func CreateTestWorkingFolder() string { + workingDir, err := CreateTempFolder() + if err != nil { + log.Fatalf("Error creating test working directory %v", err) + } + return workingDir +} diff --git a/blockchain/testutils/cmd/git-hooks.go b/blockchain/testutils/cmd/git-hooks.go new file mode 100644 index 00000000..6e22e514 --- /dev/null +++ b/blockchain/testutils/cmd/git-hooks.go @@ -0,0 +1,16 @@ +package cmd + +import ( + "log" +) + +func RunGitHooks() error { + + rootPath := GetProjectRootPath() + _, _, err := executeCommand(rootPath, "git", "config core.hooksPath scripts/githooks") + if err != nil { + log.Printf("Could not execute script: %v", err) + return err + } + return nil +} diff --git a/blockchain/testutils/cmd/hardhat.go b/blockchain/testutils/cmd/hardhat.go new file mode 100644 index 00000000..8353e48d --- /dev/null +++ b/blockchain/testutils/cmd/hardhat.go @@ -0,0 +1,125 @@ +package cmd + +import ( + "bytes" + "context" + "encoding/json" + "github.com/MadBase/MadNet/blockchain/ethereum" + "log" + "net/http" + "os" + "strconv" + "syscall" + "time" +) + +var ( + configEndpoint = "http://localhost:8545" + scriptStartHardHatNode = "hardhat_node" + envHardHatProcessId = "HARDHAT_PROCESS_ID" +) + +func IsHardHatRunning() (bool, error) { + var client = http.Client{Timeout: 2 * time.Second} + resp, err := client.Head(configEndpoint) + if err != nil { + return false, err + } + resp.Body.Close() + + if resp.StatusCode >= 200 && resp.StatusCode <= 299 { + return true, nil + } + + return false, nil +} + +func RunHardHatNode() error { + + bridgePath := GetBridgePath() + cmd, _, err := runCommand(bridgePath, "npx", "hardhat", "node", "--show-stack-traces") + if err != nil { + return err + } + + err = os.Setenv(envHardHatProcessId, strconv.Itoa(cmd.Process.Pid)) + if err != nil { + log.Printf("Error setting environment variable: %v", err) + return err + } + + return nil +} + +func WaitForHardHatNode(ctx context.Context) error { + c := http.Client{} + msg := ðereum.JsonRPCMessage{ + Version: "2.0", + ID: []byte("1"), + Method: "eth_chainId", + Params: make([]byte, 0), + } + + params, err := json.Marshal(make([]string, 0)) + if err != nil { + log.Printf("could not run hardhat node: %v", err) + return err + } + msg.Params = params + + var buff bytes.Buffer + err = json.NewEncoder(&buff).Encode(msg) + if err != nil { + log.Printf("Error creating a buffer json encoder: %v", err) + return err + } + + for { + select { + case <-ctx.Done(): + return ctx.Err() + case <-time.After(time.Second): + body := bytes.NewReader(buff.Bytes()) + _, err := c.Post( + configEndpoint, + "application/json", + body, + ) + if err != nil { + continue + } + log.Printf("HardHat node started correctly") + return nil + } + } +} + +func StopHardHat() error { + log.Printf("Stopping HardHat running instance ...") + isRunning, _ := IsHardHatRunning() + if !isRunning { + return nil + } + + pid, _ := strconv.Atoi(os.Getenv(envHardHatProcessId)) + process, err := os.FindProcess(pid) + if err != nil { + log.Printf("Error finding HardHat pid: %v", err) + return err + } + + err = process.Signal(syscall.SIGTERM) + if err != nil { + log.Printf("Error waiting sending SIGTERM signal to HardHat process: %v", err) + return err + } + + _, err = process.Wait() + if err != nil { + log.Printf("Error waiting HardHat process to stop: %v", err) + return err + } + + log.Printf("HardHat node has been stopped") + return nil +} diff --git a/blockchain/testutils/cmd/init.go b/blockchain/testutils/cmd/init.go new file mode 100644 index 00000000..e5c62acb --- /dev/null +++ b/blockchain/testutils/cmd/init.go @@ -0,0 +1,109 @@ +package cmd + +import ( + "errors" + "fmt" + "io/ioutil" + "log" + "os" + "path/filepath" + "strings" +) + +var ( + password = "abc123" +) + +func RunInit(workingDir string, numbersOfValidator int) ([]string, error) { + + // Ports + listeningPort := 4242 + p2pPort := 4343 + discoveryPort := 4444 + localStataPort := 8884 + + // Validator instance check + if numbersOfValidator < 4 || numbersOfValidator > 32 { + return nil, errors.New("number of possible validators can be from 4 up to 32") + } + + // Build validator configuration files + rootPath := GetProjectRootPath() + tempFile := temporaryFile() + passcodeFilePath := filepath.Join(workingDir, "keystores", "passcodes.txt") + passcodesFile, err := os.Create(passcodeFilePath) + if err != nil { + return nil, err + } + defer passcodesFile.Close() + + validatorAddresses := make([]string, 0) + for i := 0; i < numbersOfValidator; i++ { + + _, stdout, err := executeCommand(rootPath, "ethkey", "generate --passwordfile "+tempFile) + if err != nil { + return nil, err + } + address := string(stdout[:]) + address = strings.ReplaceAll(address, "Address: ", "") + address = strings.ReplaceAll(address, "\n", "") + validatorAddresses = append(validatorAddresses, address) + + // Generate private key + privateKey, err := RandomHex(16) // TODO - is this right? + if err != nil { + return nil, err + } + + // Validator configuration file + err = ReplaceConfigurationFile(workingDir, address, privateKey, listeningPort, p2pPort, discoveryPort, localStataPort, i) + if err != nil { + return nil, err + } + + // Passcode file + passcodesFile, err := os.OpenFile(passcodeFilePath, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0600) + if err != nil { + panic(err) + } + _, err = passcodesFile.WriteString(fmt.Sprintf("%s=%s\n", address, password)) + if err != nil { + return nil, err + } + + // Genesis + err = ReplaceGenesisBalance(workingDir) + if err != nil { + return nil, err + } + + // Keyfile.json + _, err = CopyFileToFolder(filepath.Join(rootPath, "keyfile.json"), filepath.Join(workingDir, "keystores", "keys", address)) + if err != nil { + fmt.Print("Error copying keyfile.json into generated folder") + } + err = os.Remove(filepath.Join(rootPath, "keyfile.json")) + if err != nil { + fmt.Print("Trying to remove keyfile.json ") + } + + listeningPort += 1 + p2pPort += 1 + discoveryPort += 1 + localStataPort += 1 + } + + return validatorAddresses, nil +} + +func temporaryFile() string { + f, err := ioutil.TempFile("", "") + if err != nil { + log.Fatal(err) + } + _, err = f.WriteString(password) + if err != nil { + log.Fatal(err) + } + return f.Name() +} diff --git a/blockchain/testutils/cmd/register.go b/blockchain/testutils/cmd/register.go new file mode 100644 index 00000000..6b7f2666 --- /dev/null +++ b/blockchain/testutils/cmd/register.go @@ -0,0 +1,29 @@ +package cmd + +import ( + "strings" +) + +func RunRegister(factoryAddress string, validators []string) error { + + bridgeDir := GetBridgePath() + + // iterate on validators and apass it as string array + + //validatorAddresses := make([]string, 0) + //for _, validatorAddress := range validators { + // validatorAddresses = append(validatorAddresses, validatorAddress.String()) + //} + //validatorAddresses = append(validatorAddresses, "0x61Ae54Fb4DB3d5b0f43Bd24553f69262c5Bc174d") + //validatorAddresses = append(validatorAddresses, "0x671496a9eb9cd271c05A07Bb71d52656e3c57817") + //validatorAddresses = append(validatorAddresses, "0x913cFad222B2152D5781Aae072113160eA3891Ab") + //validatorAddresses = append(validatorAddresses, "0xE3179f6517f1e5752af5C67Ba0259fA883A315E3") + + // Register validator + _, _, err := executeCommand(bridgeDir, "npx", "hardhat --network dev --show-stack-traces registerValidators --factory-address", factoryAddress, strings.Join(validators, " ")) + if err != nil { + return err + } + + return nil +} diff --git a/blockchain/testutils/cmd/setup.go b/blockchain/testutils/cmd/setup.go new file mode 100644 index 00000000..631d61cf --- /dev/null +++ b/blockchain/testutils/cmd/setup.go @@ -0,0 +1,110 @@ +package cmd + +import ( + "path/filepath" +) + +func RunSetup(workingDir string) error { + + rootPath := GetProjectRootPath() + _, err := CopyFileToFolder(filepath.Join(rootPath, "scripts", "base-files", "deploymentList"), filepath.Join(workingDir, "deploymentList")) + if err != nil { + return err + } + _, err = CopyFileToFolder(filepath.Join(rootPath, "scripts", "base-files", "deploymentArgsTemplate"), filepath.Join(workingDir, "deploymentArgsTemplate")) + if err != nil { + return err + } + _, err = CopyFileToFolder(filepath.Join(rootPath, "scripts", "base-files", "genesis.json"), filepath.Join(workingDir, "genesis.json")) + if err != nil { + return err + } + + //// Create directories + //folders := []string{ + // filepath.Join("scripts", "base-files"), + // filepath.Join("scripts", "generated", "monitorDBs"), + // filepath.Join("scripts", "generated", "config"), + // filepath.Join("scripts", "generated", "keystores"), + // filepath.Join("scripts", "generated", "keystores", "keys"), + // filepath.Join("assets", "test", "keys"), + //} + //for _, folder := range folders { + // if err := os.MkdirAll(filepath.Join(workingDir, folder), os.ModePerm); err != nil { + // fmt.Printf("Error creating configuration folders: %v", err) + // return err + // } + //} + // + //// Copy configuration files + //rootPath := GetProjectRootPath() + //configurationFileDir := filepath.Join(rootPath, "scripts", "base-files") + //files, err := ioutil.ReadDir(configurationFileDir) + //if err != nil { + // log.Fatalf("Error reading configuaration file dir path: %s", configurationFileDir) + // return err + //} + //for _, file := range files { + // src := filepath.Join(configurationFileDir, file.Name()) + // dst := filepath.Join(workingDir, "scripts", "base-files", file.Name()) + // _, err = CopyFileToFolder(src, dst) + // if err != nil { + // log.Fatalf("Error copying config file to working directory", err) + // return err + // } + //} + // + //// Copy asset files + //assetFileDir := filepath.Join(rootPath, "assets", "test", "keys") + //files, err = ioutil.ReadDir(assetFileDir) + //if err != nil { + // log.Fatalf("Error reading asset file dir path: %s", assetFileDir) + // return err + //} + //for _, file := range files { + // src := filepath.Join(assetFileDir, file.Name()) + // dst := filepath.Join(workingDir, "assets", "test", "keys", file.Name()) + // _, err = CopyFileToFolder(src, dst) + // if err != nil { + // log.Fatalf("Error copying assets file to working directory: %v", err) + // return err + // } + //} + //_, err = CopyFileToFolder(filepath.Join(rootPath, "assets", "test", "blockheaders.txt"), filepath.Join(workingDir, "assets", "test", "blockheaders.txt")) + //if err != nil { + // log.Fatalf("Error reading asset blockheaders: %s", assetFileDir) + // return err + //} + //_, err = CopyFileToFolder(filepath.Join(rootPath, "assets", "test", "passcodes.txt"), filepath.Join(workingDir, "assets", "test", "passcodes.txt")) + //if err != nil { + // log.Fatalf("Error reading asset passcodes.txt: %s", assetFileDir) + // return err + //} + //_, err = CopyFileToFolder(filepath.Join(rootPath, "scripts", "base-files", "genesis.json"), filepath.Join(workingDir, "scripts", "generated", "genesis.json")) + //if err != nil { + // log.Fatalf("Error reading asset genesis.json: %s", assetFileDir) + // return err + //} + //_, err = CopyFileToFolder(filepath.Join(rootPath, "scripts", "base-files", "0x546f99f244b7b58b855330ae0e2bc1b30b41302f"), filepath.Join(workingDir, "scripts", "generated", "keystores", "keys", "0x546f99f244b7b58b855330ae0e2bc1b30b41302f")) + //if err != nil { + // log.Fatalf("Error reading asset 0x546f99f244b7b58b855330ae0e2bc1b30b41302f: %s", assetFileDir) + // return err + //} + //_, err = CopyFileToFolder(filepath.Join(rootPath, "scripts", "base-files", "deploymentList"), filepath.Join(workingDir, "scripts", "generated", "deploymentList")) + //if err != nil { + // log.Fatalf("Error reading asset deploymentList: %s", assetFileDir) + // return err + //} + //_, err = CopyFileToFolder(filepath.Join(rootPath, "scripts", "base-files", "deploymentArgsTemplate"), filepath.Join(workingDir, "scripts", "generated", "deploymentArgsTemplate")) + //if err != nil { + // log.Fatalf("Error reading asset deploymentArgsTemplate: %s", assetFileDir) + // return err + //} + //_, err = CopyFileToFolder(filepath.Join(rootPath, "scripts", "base-files", "owner.toml"), filepath.Join(workingDir, "scripts", "generated", "owner.toml")) + //if err != nil { + // log.Fatalf("Error reading asset owner.toml: %s", assetFileDir) + // return err + //} + + return nil +} diff --git a/blockchain/testutils/cmd/validator.go b/blockchain/testutils/cmd/validator.go new file mode 100644 index 00000000..dc75acc7 --- /dev/null +++ b/blockchain/testutils/cmd/validator.go @@ -0,0 +1,38 @@ +package cmd + +import ( + "io/ioutil" + "log" + "path/filepath" + "strconv" +) + +func RunValidator(workingDir string, validatorIndex int) error { + + rootDir := GetProjectRootPath() + //validatorConfigPath := filepath.Join(workingDir, "scripts", "generated", "config", fmt.Sprintf("validator%d.toml", validatorIndex)) + + // TODO - this will be runCommand() once fixed + configurationFileDir := filepath.Join(workingDir, "scripts", "generated", "config") + files, err := ioutil.ReadDir(configurationFileDir) + for _, file := range files { + src := filepath.Join(configurationFileDir, file.Name()) + dst := filepath.Join(rootDir, "scripts", "aaa", file.Name()) + _, err := CopyFileToFolder(src, dst) + if err != nil { + log.Fatalf("Error copying config file to working directory", err) + return err + } + } + _, _, err = executeCommand(rootDir, "make", "build") + + for i := 0; i < validatorIndex; i++ { + validatorI := "validatorI" + strconv.Itoa(i) + _, _, err = executeCommand(rootDir, "./madnet", "--config", filepath.Join("scripts", "aaa", validatorI), "validator") + } + + if err != nil { + return err + } + return nil +} diff --git a/blockchain/testutils/setup.go b/blockchain/testutils/setup.go index 0489c1dd..30d27bcd 100644 --- a/blockchain/testutils/setup.go +++ b/blockchain/testutils/setup.go @@ -1,491 +1,309 @@ package testutils import ( - "bufio" "bytes" "context" "crypto/ecdsa" "encoding/json" - "fmt" - "github.com/MadBase/MadNet/logging" - "github.com/sirupsen/logrus" - "io" - "io/ioutil" - "log" - "math" - "math/big" - "net/http" - "os" - "os/exec" - "path/filepath" - "strconv" - "strings" - "syscall" - "testing" - "time" - "github.com/MadBase/MadNet/blockchain/ethereum" - "github.com/MadBase/MadNet/blockchain/transaction" - + "github.com/MadBase/MadNet/blockchain/testutils/cmd" "github.com/MadBase/MadNet/utils" "github.com/ethereum/go-ethereum/accounts" "github.com/ethereum/go-ethereum/accounts/keystore" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/crypto" + "github.com/google/uuid" "github.com/stretchr/testify/assert" + "io" + "log" + "math/big" + "net/http" + "strconv" + "strings" + "testing" ) -// SetupPrivateKeys computes deterministic private keys for testing -func SetupPrivateKeys(n int) []*ecdsa.PrivateKey { - if (n < 1) || (n >= 256) { - panic("invalid number for accounts") - } - secp256k1N, _ := new(big.Int).SetString("fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141", 16) - baseBytes := make([]byte, 32) - baseBytes[0] = 255 - baseBytes[31] = 255 - privKeyArray := []*ecdsa.PrivateKey{} - for k := 0; k < n; k++ { - privKeyBytes := utils.CopySlice(baseBytes) - privKeyBytes[1] = uint8(k) - privKeyBig := new(big.Int).SetBytes(privKeyBytes) - privKeyBig.Mod(privKeyBig, secp256k1N) - privKeyBytes = privKeyBig.Bytes() - privKey, err := crypto.ToECDSA(privKeyBytes) - if err != nil { - panic(err) - } - privKeyArray = append(privKeyArray, privKey) - } - return privKeyArray -} - -// SetAccounts derives the associated addresses from private keys -func SetupAccounts(privKeys []*ecdsa.PrivateKey) []accounts.Account { - accountsArray := []accounts.Account{} - for _, pk := range privKeys { - commonAddr := crypto.PubkeyToAddress(pk.PublicKey) - accountValue := accounts.Account{Address: commonAddr} - accountsArray = append(accountsArray, accountValue) - } - return accountsArray -} - -func GetMadnetRootPath() []string { +var ( + configEndpoint = "http://localhost:8545" + //ownerAccountAddress = "0x546f99f244b7b58b855330ae0e2bc1b30b41302f" + //password = "abc123" + configFinalityDelay = uint64(1) +) - rootPath := []string{string(os.PathSeparator)} +func BuildTestEnvironment(t *testing.T, validatorsCount int) ([]string, error) { - cmd := exec.Command("go", "list", "-m", "-f", "'{{.Dir}}'", "github.com/MadBase/MadNet") - stdout, err := cmd.Output() - if err != nil { - log.Printf("Error getting project root path: %v", err) - return rootPath - } + workingDir := cmd.CreateTestWorkingFolder() - path := string(stdout) - path = strings.ReplaceAll(path, "'", "") - path = strings.ReplaceAll(path, "\n", "") + err := cmd.RunSetup(workingDir) + assert.Nil(t, err) - pathNodes := strings.Split(path, string(os.PathSeparator)) - for _, pathNode := range pathNodes { - rootPath = append(rootPath, pathNode) - } + validatorAddresses, err := cmd.RunInit(workingDir, validatorsCount) + assert.Nil(t, err) - return rootPath + return validatorAddresses, nil } -func InitializePrivateKeysAndAccounts(n int) ([]*ecdsa.PrivateKey, []accounts.Account) { - _, pKey, err := GetOwnerAccount() - if err != nil { - panic(err) - } +func getEthereumDetails(accountMap map[accounts.Account]*ecdsa.PrivateKey, workingdir string) (*ethereum.Details, error) { - //t.Logf("owner: %v, pvKey: %v", account.Address.String(), key.PrivateKey) - privateKeys := []*ecdsa.PrivateKey{pKey} - randomPrivateKeys := SetupPrivateKeys(n - 1) - privateKeys = append(privateKeys, randomPrivateKeys...) - accounts := SetupAccounts(privateKeys) + //root := cmd.GetProjectRootPath() + //assetKey := filepath.Join(root, "assets", "test", "keys") + //assetPasscode := filepath.Join(root, "assets", "test", "passcodes.txt") + //assetKey := filepath.Join(workingDir, "scripts", "generated", "keystores", "keys") + //assetPasscode := filepath.Join(workingDir, "scripts", "generated", "keystores", "passcodes.txt") - return privateKeys, accounts + details, err := ethereum.NewEndpointWithAccount( + configEndpoint, + workingdir, + accountMap, + configFinalityDelay, + 500, + 0, + ) + return details, err } -func ReadFromFileOnRoot(filePath string, configVar string) (string, error) { - rootPath := GetMadnetRootPath() - rootPath = append(rootPath, filePath) - fileFullPath := filepath.Join(rootPath...) - - f, err := os.Open(fileFullPath) - if err != nil { - return "", err - } - defer f.Close() - - // Splits on newlines by default. - scanner := bufio.NewScanner(f) - var defaultAccount string - - // https://golang.org/pkg/bufio/#Scanner.Scan - for scanner.Scan() { - if strings.Contains(scanner.Text(), configVar) { - defaultAccount = scanner.Text() - break - } - } - - splits := strings.Split(defaultAccount, "=") - return strings.Trim(splits[1], " \""), nil +func getEthereumDetailsMap(workingDir string, accountsMap map[accounts.Account]*ecdsa.PrivateKey) (*ethereum.Details, error) { + + //root := cmd.GetProjectRootPath() + //assetKey := filepath.Join(root, "assets", "test", "keys") + //assetPasscode := filepath.Join(root, "assets", "test", "passcodes.txt") + //assetKey := filepath.Join(workingDir, "scripts", "generated", "keystores", "keys") + //assetPasscode := filepath.Join(workingDir, "scripts", "generated", "keystores", "passcodes.txt") + + // TODO - use mock + details, err := ethereum.NewEndpointWithAccount( + configEndpoint, + workingDir, + accountsMap, + configFinalityDelay, + 500, + 0, + ) + return details, err } -func GetOwnerAccount() (*common.Address, *ecdsa.PrivateKey, error) { - rootPath := GetMadnetRootPath() +func startHardHat(t *testing.T, ctx context.Context, validatorsCount int, workingDir string, accountPrivateKeyMap map[accounts.Account]*ecdsa.PrivateKey) *ethereum.Details { - // open config file owner.toml - acctAddress, err := ReadFromFileOnRoot("scripts/base-files/owner.toml", "defaultAccount") - if err != nil { - return nil, nil, err - } - acctAddressLowerCase := strings.ToLower(acctAddress) - - // open password file - passwordPath := append(rootPath, "scripts") - passwordPath = append(passwordPath, "base-files") - passwordPath = append(passwordPath, "passwordFile") - passwordFullPath := filepath.Join(passwordPath...) + log.Printf("Starting HardHat ...") + err := cmd.RunHardHatNode() + assert.Nilf(t, err, "Error starting hardhat node") - fileContent, err := ioutil.ReadFile(passwordFullPath) - if err != nil { - //log.Errorf("error opening passsword file: %v", err) - panic(err) - } + err = cmd.WaitForHardHatNode(ctx) + assert.Nilf(t, err, "Failed to wait for hardhat to be up and running") - // Convert []byte to string - password := string(fileContent) + details, err := getEthereumDetails(accountPrivateKeyMap, workingDir) + assert.Nilf(t, err, "Failed to build Ethereum endpoint") + assert.NotNilf(t, details, "Ethereum network should not be Nil") - // open wallet json file - walletPath := append(rootPath, "scripts") - walletPath = append(walletPath, "base-files") - walletPath = append(walletPath, acctAddressLowerCase) - walletFullPath := filepath.Join(walletPath...) - - jsonBytes, err := ioutil.ReadFile(walletFullPath) + log.Printf("Deploying contracts ...") + factoryAddress, err := cmd.RunDeploy(workingDir, accountPrivateKeyMap) if err != nil { - panic(err) + details.Close() + assert.Nilf(t, err, "Error deploying contracts: %v", err) + return nil } + addr := common.Address{} + copy(addr[:], common.FromHex(factoryAddress)) + details.Contracts().Initialize(ctx, addr) - key, err := keystore.DecryptKey(jsonBytes, password) - if err != nil { - panic(err) + // TODO - do I need this? + validatorAddresses := make([]string, 0) + knownAccounts := details.GetKnownAccounts() + for _, acct := range knownAccounts[:validatorsCount] { + validatorAddresses = append(validatorAddresses, acct.Address.String()) } - return &key.Address, key.PrivateKey, nil + log.Printf("Registering %d validators ...", len(validatorAddresses)) + return details } -func ConnectSimulatorEndpoint(t *testing.T, privateKeys []*ecdsa.PrivateKey, blockInterval time.Duration) ethereum.Network { - eth, err := ethereum.NewSimulator( - privateKeys, - 0, - big.NewInt(math.MaxInt64), - math.MaxInt64) - - assert.Nil(t, err, "Failed to build Ethereum endpoint...") - // assert.True(t, eth.IsEthereumAccessible(), "Web3 endpoint is not available.") +func GetEthereumNetwork(t *testing.T, cleanStart bool, validatorsCount int, workingDir string, accountPrivateKeyMap map[accounts.Account]*ecdsa.PrivateKey) ethereum.Network { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - // Unlock the default account and use it to deploy contracts - deployAccount := eth.GetDefaultAccount() - err = eth.UnlockAccount(deployAccount) - assert.Nil(t, err, "Failed to unlock default account") - - t.Logf("deploy account: %v", deployAccount.Address.String()) - - err = StartHardHatNode(eth) - if err != nil { - eth.Close() - t.Fatalf("error starting hardhat node: %v", err) + isRunning, _ := cmd.IsHardHatRunning() + if !isRunning { + log.Printf("Hardhat is not running. Start new HardHat") + details := startHardHat(t, ctx, validatorsCount, workingDir, accountPrivateKeyMap) + assert.NotNilf(t, details, "Expected details to be not nil") + return details } - t.Logf("waiting on hardhat node to start...") + if cleanStart { + err := cmd.StopHardHat() + assert.Nilf(t, err, "Failed to stopHardHat") - err = WaitForHardHatNode(ctx) - if err != nil { - eth.Close() - t.Fatalf("error: %v", err) + details := startHardHat(t, ctx, validatorsCount, workingDir, accountPrivateKeyMap) + assert.NotNilf(t, details, "Expected details to be not nil") + return details } - t.Logf("deploying contracts..") + network, err := getEthereumDetailsMap(workingDir, accountPrivateKeyMap) + assert.Nilf(t, err, "Failed to build Ethereum endpoint") + assert.NotNilf(t, network, "Ethereum network should not be Nil") - err = StartDeployScripts(eth, ctx) - if err != nil { - eth.Close() - t.Fatalf("error deploying: %v", err) - } - - validatorAddresses := make([]string, 0) - for _, acct := range eth.GetKnownAccounts() { - validatorAddresses = append(validatorAddresses, acct.Address.String()) - } - - err = RegisterValidators(eth, validatorAddresses) - assert.Nil(t, err) + return network +} - // unlock accounts - for _, account := range eth.GetKnownAccounts() { - err := eth.UnlockAccount(account) - assert.Nil(t, err) +// ======================================================== +// ======================================================== +// ======================================================== +// ======================================================== +// ======================================================== +// ======================================================== +// ======================================================== +// ======================================================== +// ======================================================== + +// GeneratePrivateKeys computes deterministic private keys for testing +func GeneratePrivateKeys(n int) []*ecdsa.PrivateKey { + if (n < 1) || (n >= 256) { + panic("invalid number for accounts") } - - // fund accounts - for _, account := range eth.GetKnownAccounts()[1:] { - txn, err := eth.TransferEther(deployAccount.Address, account.Address, big.NewInt(100000000000000000)) - assert.Nil(t, err) - assert.NotNil(t, txn) - if txn == nil { - // this shouldn't be needed, but is - eth.Close() - t.Fatal("could not transfer ether") + secp256k1N, _ := new(big.Int).SetString("fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141", 16) + baseBytes := make([]byte, 32) + baseBytes[0] = 255 + baseBytes[31] = 255 + privKeyArray := []*ecdsa.PrivateKey{} + for k := 0; k < n; k++ { + privKeyBytes := utils.CopySlice(baseBytes) + privKeyBytes[1] = uint8(k) + privKeyBig := new(big.Int).SetBytes(privKeyBytes) + privKeyBig.Mod(privKeyBig, secp256k1N) + privKeyBytes = privKeyBig.Bytes() + privKey, err := crypto.ToECDSA(privKeyBytes) + if err != nil { + panic(err) } - watcher := transaction.NewWatcher(eth.GetClient(), transaction.NewKnownSelectors(), eth.GetFinalityDelay()) - watcher.StartLoop() - - rcpt, err := watcher.SubscribeAndWait(ctx, txn) - assert.Nil(t, err) - assert.NotNil(t, rcpt) + privKeyArray = append(privKeyArray, privKey) } - - return eth + return privKeyArray } -func Setup(finalityDelay uint64, numAccounts int, registryAddress common.Address) (ethereum.Network, *logrus.Logger, error) { - logger := logging.GetLogger("test") - logger.SetLevel(logrus.TraceLevel) - ecdsaPrivateKeys, _ := InitializePrivateKeysAndAccounts(numAccounts) - eth, err := ethereum.NewSimulator( - ecdsaPrivateKeys, - 6, - 10*time.Second, - 30*time.Second, - 0, - big.NewInt(math.MaxInt64), - 50, - math.MaxInt64) - if err != nil { - return nil, logger, err - } - - eth.SetFinalityDelay(finalityDelay) - knownSelectors := transaction.NewKnownSelectors() - transaction := transaction.NewWatcher(eth.GetClient(), knownSelectors, 5) - transaction.SetNumOfConfirmationBlocks(finalityDelay) - - //todo: redeploy and get the registryAddress here - err = eth.Contracts().LookupContracts(context.Background(), registryAddress) - if err != nil { - return nil, logger, err +// GenerateAccounts derives the associated addresses from private keys +func GenerateAccounts(privKeys []*ecdsa.PrivateKey) []accounts.Account { + accountsArray := []accounts.Account{} + for _, pk := range privKeys { + commonAddr := crypto.PubkeyToAddress(pk.PublicKey) + accountValue := accounts.Account{Address: commonAddr} + accountsArray = append(accountsArray, accountValue) } - return eth, logger, nil + return accountsArray } -func StartHardHatNode(eth *ethereum.Details) error { - - rootPath := GetMadnetRootPath() - scriptPath := append(rootPath, "scripts") - scriptPath = append(scriptPath, "main.sh") - scriptPathJoined := filepath.Join(scriptPath...) - fmt.Println("scriptPathJoined2: ", scriptPathJoined) - - cmd := exec.Cmd{ - Path: scriptPathJoined, - Args: []string{scriptPathJoined, "hardhat_node"}, - Dir: filepath.Join(rootPath...), - } - - setCommandStdOut(&cmd) - err := cmd.Start() - // if there is an error with our execution - // handle it here +func InitializePrivateKeysAndAccountsMap(n int) map[accounts.Account]*ecdsa.PrivateKey { + _, ownerPrivateKey, err := GetOwnerAccount() if err != nil { - return fmt.Errorf("could not run hardhat node: %s", err) + // TODO - don't think panic is the right solution here + panic(err) } - eth.SetClose(func() error { - fmt.Printf("closing hardhat node %v..\n", cmd.Process.Pid) - err := cmd.Process.Signal(syscall.SIGTERM) - if err != nil { - return err - } - - _, err = cmd.Process.Wait() - if err != nil { - return err - } - - fmt.Printf("hardhat node closed\n") - return nil - }) + privateKeys := []*ecdsa.PrivateKey{ownerPrivateKey} + randomPrivateKeys := GeneratePrivateKeys(n) + log.Printf("********** 2 - Generated %d private keys", n) - return nil -} - -// setCommandStdOut If ENABLE_SCRIPT_LOG env variable is set as 'true' the command will show scripts logs -func setCommandStdOut(cmd *exec.Cmd) { - - flagValue, found := os.LookupEnv("ENABLE_SCRIPT_LOG") - enabled, err := strconv.ParseBool(flagValue) + privateKeys = append(privateKeys, randomPrivateKeys...) + accountsMap := GenerateAccountsMap(privateKeys) + log.Printf("********** 3 - Generated account Map with %d elements\n", len(accountsMap)) - if err == nil && found && enabled { - cmd.Stdout = os.Stdout - cmd.Stderr = os.Stderr - } else { - cmd.Stdout = io.Discard - cmd.Stderr = io.Discard + for k, v := range accountsMap { + log.Printf(" Account Address: %s - Private Key %s\n", k.Address.String(), v) } + return accountsMap } -func InitializeValidatorFiles(n int) error { - - rootPath := GetMadnetRootPath() - scriptPath := append(rootPath, "scripts") - scriptPath = append(scriptPath, "main.sh") - scriptPathJoined := filepath.Join(scriptPath...) - fmt.Println("scriptPathJoined2: ", scriptPathJoined) - - cmd := exec.Cmd{ - Path: scriptPathJoined, - Args: []string{scriptPathJoined, "init", strconv.Itoa(n)}, - Dir: filepath.Join(rootPath...), - } - - setCommandStdOut(&cmd) - err := cmd.Start() - if err != nil { - return fmt.Errorf("could not generate validator files: %s", err) +// GenerateAccountsMap derives the associated addresses from private keys +func GenerateAccountsMap(privKeys []*ecdsa.PrivateKey) map[accounts.Account]*ecdsa.PrivateKey { + accountPrivateKeyMap := make(map[accounts.Account]*ecdsa.PrivateKey) + for _, pk := range privKeys { + commonAddr := crypto.PubkeyToAddress(pk.PublicKey) + accountValue := accounts.Account{Address: commonAddr} + accountPrivateKeyMap[accountValue] = pk } - - return nil + return accountPrivateKeyMap } -func StartDeployScripts(eth *ethereum.Details, ctx context.Context) error { - - rootPath := GetMadnetRootPath() - scriptPath := append(rootPath, "scripts") - scriptPath = append(scriptPath, "main.sh") - scriptPathJoined := filepath.Join(scriptPath...) - fmt.Println("scriptPathJoined: ", scriptPathJoined) - - err := os.Setenv("SKIP_REGISTRATION", "1") - if err != nil { - return err - } - - cmd := exec.Cmd{ - Path: scriptPathJoined, - Args: []string{scriptPathJoined, "deploy"}, - Dir: filepath.Join(rootPath...), - } - - setCommandStdOut(&cmd) - err = cmd.Run() - - // if there is an error with our execution - // handle it here - if err != nil { - log.Printf("Could not execute deploy script: %s", err) - return err - } - - // inits contracts - factory, err := ReadFromFileOnRoot("scripts/generated/factoryState", "defaultFactoryAddress") +func InitializePrivateKeysAndAccounts(n int) ([]*ecdsa.PrivateKey, []accounts.Account) { + _, pKey, err := GetOwnerAccount() if err != nil { - return err + // TODO - don't think panic is the right solution here + panic(err) } - addr := common.Address{} - copy(addr[:], common.FromHex(factory)) - eth.Contracts().Initialize(ctx, addr) + privateKeys := []*ecdsa.PrivateKey{pKey} + randomPrivateKeys := GeneratePrivateKeys(n - 1) + privateKeys = append(privateKeys, randomPrivateKeys...) + accounts := GenerateAccounts(privateKeys) - return nil + return privateKeys, accounts } -func WaitForHardHatNode(ctx context.Context) error { - c := http.Client{} - msg := ðereum.JsonRPCMessage{ - Version: "2.0", - ID: []byte("1"), - Method: "eth_chainId", - Params: make([]byte, 0), - } - var err error - if msg.Params, err = json.Marshal(make([]string, 0)); err != nil { - panic(err) - } +func GetOwnerAccount() (*common.Address, *ecdsa.PrivateKey, error) { + defaultOwnerAccount := strings.ToLower("0x546F99F244b7B58B855330AE0E2BC1b30b41302F") + id, _ := uuid.Parse("6b2a0716-b444-46c3-a1e3-2936ddd8ecc5") + pk, _ := crypto.HexToECDSA("6aea45ee1273170fb525da34015e4f20ba39fe792f486ba74020bcacc9badfc1") + addr := common.HexToAddress(defaultOwnerAccount) + key := &keystore.Key{ + Id: id, + Address: addr, + PrivateKey: pk, + } + log.Printf("********** 1 - OWNER ACCOUNT\n Address:%s\n PK: %s\n\n", &key.Address, key.PrivateKey) + return &key.Address, key.PrivateKey, nil +} - var buff bytes.Buffer - err = json.NewEncoder(&buff).Encode(msg) +//func Setup(finalityDelay uint64, numAccounts int, registryAddress common.Address) (ethereum.Network, *logrus.Logger, error) { +// logger := logging.GetLogger("test") +// logger.SetLevel(logrus.TraceLevel) +// ecdsaPrivateKeys, _ := InitializePrivateKeysAndAccounts(numAccounts) +// eth, err := ethereum.NewSimulator( +// ecdsaPrivateKeys, +// 6, +// 10*time.Second, +// 30*time.Second, +// 0, +// big.NewInt(math.MaxInt64), +// 50, +// math.MaxInt64) +// if err != nil { +// return nil, logger, err +// } +// +// eth.SetFinalityDelay(finalityDelay) +// knownSelectors := transaction.NewKnownSelectors() +// transaction := transaction.NewWatcher(eth.GetClient(), knownSelectors, 5) +// transaction.SetNumOfConfirmationBlocks(finalityDelay) +// +// //todo: redeploy and get the registryAddress here +// err = eth.Contracts().LookupContracts(context.Background(), registryAddress) +// if err != nil { +// return nil, logger, err +// } +// return eth, logger, nil +//} + +func Init(workingDir string, n int) error { + + // Resources setup + err := cmd.RunSetup(workingDir) if err != nil { return err } - reader := bytes.NewReader(buff.Bytes()) - - for { - select { - case <-ctx.Done(): - return ctx.Err() - case <-time.After(time.Second): - resp, err := c.Post( - "http://127.0.0.1:8545", - "application/json", - reader, - ) - if err != nil { - continue - } - _, err = io.ReadAll(resp.Body) - if err == nil { - return nil - } - } - - } -} - -func RegisterValidators(eth *ethereum.Details, validatorAddresses []string) error { - - rootPath := GetMadnetRootPath() - scriptPath := append(rootPath, "scripts") - scriptPath = append(scriptPath, "main.sh") - scriptPathJoined := filepath.Join(scriptPath...) - fmt.Println("scriptPathJoined: ", scriptPathJoined) - - args := []string{ - scriptPathJoined, - "register_test", - eth.Contracts().ContractFactoryAddress().String(), - } - args = append(args, validatorAddresses...) - - cmd := exec.Cmd{ - Path: scriptPathJoined, - Args: args, - Dir: filepath.Join(rootPath...), - } - - setCommandStdOut(&cmd) - err := cmd.Run() - - // if there is an error with our execution - // handle it here - if err != nil { - return fmt.Errorf("could not execute deploy script: %s", err) - } + // TODO - change this to be global + //SetCommandStdOut(&cmd) + //err = cmd.Start() + //if err != nil { + // return err + //} return nil } -// send a command to the hardhat server via an RPC call -func SendHardhatCommand(command string, params ...interface{}) error { +// TODO - check this one +// sendHardhatCommand sends a command to the hardhat server via an RPC call +func sendHardhatCommand(command string, params ...interface{}) error { commandJson := ðereum.JsonRPCMessage{ Version: "2.0", @@ -498,7 +316,6 @@ func SendHardhatCommand(command string, params ...interface{}) error { if err != nil { return err } - commandJson.Params = paramsJson c := http.Client{} @@ -508,14 +325,12 @@ func SendHardhatCommand(command string, params ...interface{}) error { return err } - reader := bytes.NewReader(buff.Bytes()) - + body := bytes.NewReader(buff.Bytes()) resp, err := c.Post( - "http://127.0.0.1:8545", + configEndpoint, "application/json", - reader, + body, ) - if err != nil { return err } @@ -527,18 +342,18 @@ func SendHardhatCommand(command string, params ...interface{}) error { return nil } -// mine a certain number of hardhat blocks -func MineBlocks(t *testing.T, eth ethereum.Network, blocksToMine uint64) { +// MineBlocks mines a certain number of hardhat blocks +func MineBlocks(eth ethereum.Network, blocksToMine uint64) { var blocksToMineString = "0x" + strconv.FormatUint(blocksToMine, 16) log.Printf("hardhat_mine %v blocks ", blocksToMine) - err := SendHardhatCommand("hardhat_mine", blocksToMineString) + err := sendHardhatCommand("hardhat_mine", blocksToMineString) if err != nil { panic(err) } } // advance to a certain block number -func AdvanceTo(t *testing.T, eth ethereum.Network, target uint64) { +func AdvanceTo(eth ethereum.Network, target uint64) { currentBlock, err := eth.GetCurrentHeight(context.Background()) if err != nil { panic(err) @@ -551,27 +366,26 @@ func AdvanceTo(t *testing.T, eth ethereum.Network, target uint64) { log.Printf("hardhat_mine %v blocks to target height %v", blocksToMine, target) - err = SendHardhatCommand("hardhat_mine", blocksToMineString) + err = sendHardhatCommand("hardhat_mine", blocksToMineString) if err != nil { panic(err) } } -// The the Base fee for the next hardhat block. Can be used to make tx stale. -func SetNextBlockBaseFee(t *testing.T, eth ethereum.Network, target uint64) { +// SetNextBlockBaseFee The Base fee for the next hardhat block. Can be used to make tx stale. +func SetNextBlockBaseFee(target uint64) { log.Printf("Setting hardhat_setNextBlockBaseFeePerGas to %v", target) - - err := SendHardhatCommand("hardhat_setNextBlockBaseFeePerGas", "0x"+strconv.FormatUint(target, 16)) + err := sendHardhatCommand("hardhat_setNextBlockBaseFeePerGas", "0x"+strconv.FormatUint(target, 16)) if err != nil { panic(err) } } -// Enable/disable hardhat autoMine +// Enable/disable hardhat autoMine TODO - check this one func SetAutoMine(t *testing.T, eth ethereum.Network, autoMine bool) { log.Printf("Setting Automine to %v", autoMine) - err := SendHardhatCommand("evm_setAutomine", autoMine) + err := sendHardhatCommand("evm_setAutomine", autoMine) if err != nil { panic(err) } @@ -583,7 +397,7 @@ func SetAutoMine(t *testing.T, eth ethereum.Network, autoMine bool) { func SetBlockInterval(t *testing.T, eth ethereum.Network, intervalInMilliSeconds uint64) { SetAutoMine(t, eth, false) log.Printf("Setting block interval to %v seconds", intervalInMilliSeconds) - err := SendHardhatCommand("evm_setIntervalMining", intervalInMilliSeconds) + err := sendHardhatCommand("evm_setIntervalMining", intervalInMilliSeconds) if err != nil { panic(err) } diff --git a/blockchain/testutils/setup_test.go b/blockchain/testutils/setup_test.go new file mode 100644 index 00000000..56026b1e --- /dev/null +++ b/blockchain/testutils/setup_test.go @@ -0,0 +1,29 @@ +package testutils + +import ( + "github.com/MadBase/MadNet/blockchain/ethereum" + "reflect" + "testing" +) + +func TestConnectSimulatorEndpoint(t *testing.T) { + + tests := []struct { + name string + cleanStart bool + want ethereum.Network + }{ + { + name: "HardHat not running", + cleanStart: true, + want: nil, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := GetEthereumNetwork(t, tt.cleanStart, 8, ""); !reflect.DeepEqual(got, tt.want) { + t.Errorf("GetEthereumNetwork() = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/blockchain/transaction/transaction.go b/blockchain/transaction/transaction.go index 2abeb7e7..3f73165f 100644 --- a/blockchain/transaction/transaction.go +++ b/blockchain/transaction/transaction.go @@ -214,24 +214,24 @@ type WatcherBackend struct { requestChannel <-chan subscribeRequest // Channel used to send request to this backend service } -func (b *WatcherBackend) Loop() { +func (wb *WatcherBackend) Loop() { poolingTime := time.After(constants.TxPollingTime) for { select { - case req, ok := <-b.requestChannel: + case req, ok := <-wb.requestChannel: if !ok { - b.logger.Debugf("request channel closed, exiting") + wb.logger.Debugf("request channel closed, exiting") return } if req.responseChannel == nil { - b.logger.Debug("Invalid request for txn without a response channel, ignoring") + wb.logger.Debug("Invalid request for txn without a response channel, ignoring") continue } - b.queue(req) + wb.queue(req) case <-poolingTime: - b.collectReceipts() + wb.collectReceipts() poolingTime = time.After(constants.TxPollingTime) } } @@ -638,6 +638,7 @@ func NewWatcher(client ethereum.Network, selectMap interfaces.ISelectorMap, txCo client: client, logger: logger.WithField("Component", "TransactionWatcherBackend"), monitoredTxns: make(map[common.Hash]info), + retryGroups: make(map[uint64]uint64), receiptCache: make(map[common.Hash]receipt), aggregates: make(map[objects.FuncSelector]Profile), knownSelectors: selectMap, @@ -661,15 +662,15 @@ func WatcherFromNetwork(network ethereum.Network) *Watcher { } // Start the transaction watcher service -func (f *Watcher) StartLoop() { - go f.backend.Loop() +func (w *Watcher) StartLoop() { + go w.backend.Loop() } // Close the transaction watcher service -func (f *Watcher) Close() { - f.logger.Debug("closing request channel...") - close(f.requestChannel) - f.closeMainContext() +func (w *Watcher) Close() { + w.logger.Debug("closing request channel...") + close(w.requestChannel) + w.closeMainContext() } // Subscribe a transaction to be watched by the transaction watcher service. If @@ -678,14 +679,14 @@ func (f *Watcher) Close() { // final tx hash in the receipt can be different from the initial txn sent. This // can happen if the txn got stale and the watcher did a transaction replace // with higher fees. -func (tw *Watcher) Subscribe(ctx context.Context, txn *types.Transaction) (<-chan *objects.ReceiptResponse, error) { - tw.logger.WithField("Txn", txn.Hash().Hex()).Debug("Subscribing for a transaction") - respChannel := NewResponseChannel[SubscribeResponse](tw.logger) +func (w *Watcher) Subscribe(ctx context.Context, txn *types.Transaction) (<-chan *objects.ReceiptResponse, error) { + w.logger.WithField("Txn", txn.Hash().Hex()).Debug("Subscribing for a transaction") + respChannel := NewResponseChannel[SubscribeResponse](w.logger) defer respChannel.CloseChannel() req := subscribeRequest{txn: txn, responseChannel: respChannel} select { - case tw.requestChannel <- req: + case w.requestChannel <- req: case <-ctx.Done(): return nil, &ErrInvalidTransactionRequest{fmt.Sprintf("context cancelled reqChannel: %v", ctx.Err())} } @@ -700,7 +701,7 @@ func (tw *Watcher) Subscribe(ctx context.Context, txn *types.Transaction) (<-cha // function that wait for a transaction receipt. This is blocking function that // will wait for a response in the input receiptResponseChannel -func (f *Watcher) Wait(ctx context.Context, receiptResponseChannel <-chan *objects.ReceiptResponse) (*types.Receipt, error) { +func (w *Watcher) Wait(ctx context.Context, receiptResponseChannel <-chan *objects.ReceiptResponse) (*types.Receipt, error) { select { case receiptResponse := <-receiptResponseChannel: return receiptResponse.Receipt, receiptResponse.Err @@ -710,15 +711,15 @@ func (f *Watcher) Wait(ctx context.Context, receiptResponseChannel <-chan *objec } // Queue a transaction and wait for its receipt -func (f *Watcher) SubscribeAndWait(ctx context.Context, txn *types.Transaction) (*types.Receipt, error) { - receiptResponseChannel, err := f.Subscribe(ctx, txn) +func (w *Watcher) SubscribeAndWait(ctx context.Context, txn *types.Transaction) (*types.Receipt, error) { + receiptResponseChannel, err := w.Subscribe(ctx, txn) if err != nil { return nil, err } - return f.Wait(ctx, receiptResponseChannel) + return w.Wait(ctx, receiptResponseChannel) } -func (f *Watcher) Status(ctx context.Context) error { - f.logger.Error("Status function not implemented yet") +func (w *Watcher) Status(ctx context.Context) error { + w.logger.Error("Status function not implemented yet") return nil } diff --git a/blockchain/transaction/transaction_test.go b/blockchain/transaction/transaction_test.go index a8681c76..202f6db7 100644 --- a/blockchain/transaction/transaction_test.go +++ b/blockchain/transaction/transaction_test.go @@ -170,7 +170,7 @@ func TestSubscribeAndWaitForStaleTx(t *testing.T) { testutils.SetBlockInterval(t, eth, 500) // setting base fee to 10k GWei - testutils.SetNextBlockBaseFee(t, eth, 10_000_000_000_000) + testutils.SetNextBlockBaseFee(10_000_000_000_000) accounts := eth.GetKnownAccounts() assert.Equal(t, numAccounts, len(accounts)) diff --git a/cmd/main.go b/cmd/main.go index b6ca3f6e..ccf33995 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -209,6 +209,8 @@ func main() { cFlags.IntVarP(intPtr, o.name, o.short, 0, o.usage) } else if uint64Ptr, ok := o.value.(*uint64); ok { cFlags.Uint64VarP(uint64Ptr, o.name, o.short, 0, o.usage) + } else if uint32Ptr, ok := o.value.(*uint32); ok { + cFlags.Uint32VarP(uint32Ptr, o.name, o.short, 0, o.usage) } else if boolPtr, ok := o.value.(*bool); ok { cFlags.BoolVarP(boolPtr, o.name, o.short, false, o.usage) } else { diff --git a/scripts/base-scripts/register.sh b/scripts/base-scripts/register.sh index 14671ae7..29367d84 100755 --- a/scripts/base-scripts/register.sh +++ b/scripts/base-scripts/register.sh @@ -14,6 +14,9 @@ if [[ -z "${FACTORY_ADDRESS}" ]]; then exit 1 fi + + # TODO - NO NEEDED +# CONTROL on which account will be validators (once we got the address of the factory) npx hardhat --network "$NETWORK" --show-stack-traces registerValidators --factory-address "$FACTORY_ADDRESS" $ADDRESSES