From 8d33206bb846a24a7edee77e4d748f863caa3440 Mon Sep 17 00:00:00 2001 From: Roman Khimov Date: Thu, 1 Sep 2022 17:52:44 +0300 Subject: [PATCH] *: don't get private key from account if just public one is needed Add PublicKey() API to the Account and use it as appropriate, avoid creating additional references to the private key. --- cli/contract_test.go | 2 +- cli/smartcontract/manifest.go | 2 +- cli/wallet/multisig.go | 2 +- cli/wallet/validator.go | 4 ++-- internal/basicchain/basic.go | 4 ++-- internal/contracts/contracts_test.go | 2 +- pkg/consensus/consensus.go | 4 +--- pkg/consensus/consensus_test.go | 2 +- pkg/core/blockchain_neotest_test.go | 6 ++--- pkg/core/native/native_test/neo_test.go | 26 +++++++++++----------- pkg/core/native/native_test/oracle_test.go | 4 ++-- pkg/neotest/chain/chain.go | 14 ++++++------ pkg/neotest/signer.go | 4 ++-- pkg/neotest/signer_test.go | 6 ++--- pkg/services/notary/core_test.go | 18 +++++++-------- pkg/services/notary/node.go | 2 +- pkg/services/notary/node_test.go | 8 +++---- pkg/services/oracle/oracle_test.go | 14 ++++++------ pkg/services/stateroot/service_test.go | 8 +++---- pkg/services/stateroot/validators.go | 2 +- pkg/wallet/account.go | 11 ++++++++- pkg/wallet/account_test.go | 5 +++-- 22 files changed, 79 insertions(+), 71 deletions(-) diff --git a/cli/contract_test.go b/cli/contract_test.go index fcea7c4ac..d0cc32596 100644 --- a/cli/contract_test.go +++ b/cli/contract_test.go @@ -802,7 +802,7 @@ func TestComlileAndInvokeFunction(t *testing.T) { require.NoError(t, err) pk, err := keys.NewPrivateKey() require.NoError(t, err) - err = acc.ConvertMultisig(2, keys.PublicKeys{acc.PrivateKey().PublicKey(), pk.PublicKey()}) + err = acc.ConvertMultisig(2, keys.PublicKeys{acc.PublicKey(), pk.PublicKey()}) require.NoError(t, err) t.Run("cosigner is multisig account", func(t *testing.T) { diff --git a/cli/smartcontract/manifest.go b/cli/smartcontract/manifest.go index 498e66f77..a20325208 100644 --- a/cli/smartcontract/manifest.go +++ b/cli/smartcontract/manifest.go @@ -45,7 +45,7 @@ func manifestAddGroup(ctx *cli.Context) error { var found bool sig := gAcc.PrivateKey().Sign(h.BytesBE()) - pub := gAcc.PrivateKey().PublicKey() + pub := gAcc.PublicKey() for i := range m.Groups { if m.Groups[i].PublicKey.Equal(pub) { m.Groups[i].Signature = sig diff --git a/cli/wallet/multisig.go b/cli/wallet/multisig.go index 114dcdf2f..e489a42ef 100644 --- a/cli/wallet/multisig.go +++ b/cli/wallet/multisig.go @@ -60,7 +60,7 @@ func signStoredTransaction(ctx *cli.Context) error { if acc.CanSign() { priv := acc.PrivateKey() sign := priv.SignHashable(uint32(pc.Network), pc.Verifiable) - if err := pc.AddSignature(ch, acc.Contract, priv.PublicKey(), sign); err != nil { + if err := pc.AddSignature(ch, acc.Contract, acc.PublicKey(), sign); err != nil { return cli.NewExitError(fmt.Errorf("can't add signature: %w", err), 1) } } else if rpcNode == "" { diff --git a/cli/wallet/validator.go b/cli/wallet/validator.go index 09717b46b..ef4726e27 100644 --- a/cli/wallet/validator.go +++ b/cli/wallet/validator.go @@ -76,13 +76,13 @@ func newValidatorCommands() []cli.Command { func handleRegister(ctx *cli.Context) error { return handleNeoAction(ctx, func(contract *neo.Contract, _ util.Uint160, acc *wallet.Account) (*transaction.Transaction, error) { - return contract.RegisterCandidateUnsigned(acc.PrivateKey().PublicKey()) + return contract.RegisterCandidateUnsigned(acc.PublicKey()) }) } func handleUnregister(ctx *cli.Context) error { return handleNeoAction(ctx, func(contract *neo.Contract, _ util.Uint160, acc *wallet.Account) (*transaction.Transaction, error) { - return contract.UnregisterCandidateUnsigned(acc.PrivateKey().PublicKey()) + return contract.UnregisterCandidateUnsigned(acc.PublicKey()) }) } diff --git a/internal/basicchain/basic.go b/internal/basicchain/basic.go index f0071cfd3..304ff53c8 100644 --- a/internal/basicchain/basic.go +++ b/internal/basicchain/basic.go @@ -144,8 +144,8 @@ func Init(t *testing.T, rootpath string, e *neotest.Executor) { require.NoError(t, err) require.NoError(t, ntr.Accounts[0].Decrypt("one", ntr.Scrypt)) designateSuperInvoker.Invoke(t, stackitem.Null{}, "designateAsRole", - int64(noderoles.P2PNotary), []interface{}{ntr.Accounts[0].PrivateKey().PublicKey().Bytes()}) - t.Logf("Designated Notary node: %s", hex.EncodeToString(ntr.Accounts[0].PrivateKey().PublicKey().Bytes())) + int64(noderoles.P2PNotary), []interface{}{ntr.Accounts[0].PublicKey().Bytes()}) + t.Logf("Designated Notary node: %s", hex.EncodeToString(ntr.Accounts[0].PublicKey().Bytes())) // Block #10: push verification contract with arguments into the chain. verifyPath = filepath.Join(testDataPrefix, "verify_args", "verification_with_args_contract.go") diff --git a/internal/contracts/contracts_test.go b/internal/contracts/contracts_test.go index e9e027b36..743bbb234 100644 --- a/internal/contracts/contracts_test.go +++ b/internal/contracts/contracts_test.go @@ -74,7 +74,7 @@ func generateManagementHelperContracts(t *testing.T, saveState bool) { stdHash := e.NativeHash(t, nativenames.StdLib) neoHash := e.NativeHash(t, nativenames.Neo) singleChainValidatorAcc := e.Validator.(neotest.MultiSigner).Single(2).Account() // priv0 - require.NoError(t, singleChainValidatorAcc.ConvertMultisig(1, keys.PublicKeys{singleChainValidatorAcc.PrivateKey().PublicKey()})) + require.NoError(t, singleChainValidatorAcc.ConvertMultisig(1, keys.PublicKeys{singleChainValidatorAcc.PublicKey()})) singleChainValidatorHash := singleChainValidatorAcc.Contract.ScriptHash() w := io.NewBufBinWriter() diff --git a/pkg/consensus/consensus.go b/pkg/consensus/consensus.go index f4cec74fb..38326225a 100644 --- a/pkg/consensus/consensus.go +++ b/pkg/consensus/consensus.go @@ -377,17 +377,15 @@ func (s *service) getKeyPair(pubs []crypto.PublicKey) (int, crypto.PrivateKey, c continue } - key := acc.PrivateKey() if acc.PrivateKey() == nil { err := acc.Decrypt(s.Config.Wallet.Password, s.wallet.Scrypt) if err != nil { s.log.Fatal("can't unlock account", zap.String("address", address.Uint160ToString(sh))) break } - key = acc.PrivateKey() } - return i, &privateKey{PrivateKey: key}, &publicKey{PublicKey: key.PublicKey()} + return i, &privateKey{PrivateKey: acc.PrivateKey()}, &publicKey{PublicKey: acc.PublicKey()} } return -1, nil, nil diff --git a/pkg/consensus/consensus_test.go b/pkg/consensus/consensus_test.go index 754bb74b0..92aa0a7cc 100644 --- a/pkg/consensus/consensus_test.go +++ b/pkg/consensus/consensus_test.go @@ -115,7 +115,7 @@ func initServiceNextConsensus(t *testing.T, newAcc *wallet.Account, offset uint3 func TestService_NextConsensus(t *testing.T) { newAcc, err := wallet.NewAccount() require.NoError(t, err) - script, err := smartcontract.CreateMajorityMultiSigRedeemScript(keys.PublicKeys{newAcc.PrivateKey().PublicKey()}) + script, err := smartcontract.CreateMajorityMultiSigRedeemScript(keys.PublicKeys{newAcc.PublicKey()}) require.NoError(t, err) checkNextConsensus := func(t *testing.T, bc *core.Blockchain, height uint32, h util.Uint160) { diff --git a/pkg/core/blockchain_neotest_test.go b/pkg/core/blockchain_neotest_test.go index 35d5bc3a1..ffe9f23ba 100644 --- a/pkg/core/blockchain_neotest_test.go +++ b/pkg/core/blockchain_neotest_test.go @@ -1060,7 +1060,7 @@ func TestBlockchain_VerifyTx(t *testing.T) { notaryServiceFeePerKey := bc.GetNotaryServiceFeePerKey() oracleAcc := accs[2] - oraclePubs := keys.PublicKeys{oracleAcc.PrivateKey().PublicKey()} + oraclePubs := keys.PublicKeys{oracleAcc.PublicKey()} require.NoError(t, oracleAcc.ConvertMultisig(1, oraclePubs)) neoHash := e.NativeHash(t, nativenames.Neo) @@ -1179,7 +1179,7 @@ func TestBlockchain_VerifyTx(t *testing.T) { }) t.Run("CalculateNetworkFee, multisignature script", func(t *testing.T) { multisigAcc := accs[4] - pKeys := keys.PublicKeys{multisigAcc.PrivateKey().PublicKey()} + pKeys := keys.PublicKeys{multisigAcc.PublicKey()} require.NoError(t, multisigAcc.ConvertMultisig(1, pKeys)) multisigHash := hash.Hash160(multisigAcc.Contract.Script) tx := newTestTx(t, multisigHash, testScript) @@ -1594,7 +1594,7 @@ func TestBlockchain_VerifyTx(t *testing.T) { notary, err := wallet.NewAccount() require.NoError(t, err) designateSuperInvoker.Invoke(t, stackitem.Null{}, "designateAsRole", - int64(noderoles.P2PNotary), []interface{}{notary.PrivateKey().PublicKey().Bytes()}) + int64(noderoles.P2PNotary), []interface{}{notary.PublicKey().Bytes()}) txSetNotary := transaction.New([]byte{byte(opcode.RET)}, 0) txSetNotary.Signers = []transaction.Signer{ { diff --git a/pkg/core/native/native_test/neo_test.go b/pkg/core/native/native_test/neo_test.go index 6d8ee3275..ef9e62433 100644 --- a/pkg/core/native/native_test/neo_test.go +++ b/pkg/core/native/native_test/neo_test.go @@ -65,7 +65,7 @@ func TestNEO_CandidateEvents(t *testing.T) { singleSigner := c.Signers[0].(neotest.MultiSigner).Single(0) cc := c.WithSigners(c.Signers[0], singleSigner) e := c.Executor - pkb := singleSigner.Account().PrivateKey().PublicKey().Bytes() + pkb := singleSigner.Account().PublicKey().Bytes() // Register 1 -> event tx := cc.Invoke(t, true, "registerCandidate", pkb) @@ -160,13 +160,13 @@ func TestNEO_Vote(t *testing.T) { transferTx = neoValidatorsInvoker.PrepareInvoke(t, "transfer", e.Validator.ScriptHash(), referenceAccounts[i].(neotest.SingleSigner).Account().PrivateKey().GetScriptHash(), int64(committeeSize+1-i)*1000000, nil) txes = append(txes, transferTx) if i > 0 { - registerTx := neoValidatorsInvoker.WithSigners(candidates[i]).PrepareInvoke(t, "registerCandidate", candidates[i].(neotest.SingleSigner).Account().PrivateKey().PublicKey().Bytes()) + registerTx := neoValidatorsInvoker.WithSigners(candidates[i]).PrepareInvoke(t, "registerCandidate", candidates[i].(neotest.SingleSigner).Account().PublicKey().Bytes()) txes = append(txes, registerTx) - voteTx := neoValidatorsInvoker.WithSigners(voters[i]).PrepareInvoke(t, "vote", voters[i].(neotest.SingleSigner).Account().PrivateKey().GetScriptHash(), candidates[i].(neotest.SingleSigner).Account().PrivateKey().PublicKey().Bytes()) + voteTx := neoValidatorsInvoker.WithSigners(voters[i]).PrepareInvoke(t, "vote", voters[i].(neotest.SingleSigner).Account().PrivateKey().GetScriptHash(), candidates[i].(neotest.SingleSigner).Account().PublicKey().Bytes()) txes = append(txes, voteTx) } } - txes = append(txes, policyInvoker.PrepareInvoke(t, "blockAccount", candidates[len(candidates)-1].(neotest.SingleSigner).Account().PrivateKey().PublicKey().GetScriptHash())) + txes = append(txes, policyInvoker.PrepareInvoke(t, "blockAccount", candidates[len(candidates)-1].(neotest.SingleSigner).Account().PublicKey().GetScriptHash())) neoValidatorsInvoker.AddNewBlock(t, txes...) for _, tx := range txes { e.CheckHalt(t, tx.Hash(), stackitem.Make(true)) // luckily, both `transfer`, `registerCandidate` and `vote` return boolean values @@ -184,9 +184,9 @@ func TestNEO_Vote(t *testing.T) { // Register and give some value to the last validator. txes = txes[:0] - registerTx := neoValidatorsInvoker.WithSigners(candidates[0]).PrepareInvoke(t, "registerCandidate", candidates[0].(neotest.SingleSigner).Account().PrivateKey().PublicKey().Bytes()) + registerTx := neoValidatorsInvoker.WithSigners(candidates[0]).PrepareInvoke(t, "registerCandidate", candidates[0].(neotest.SingleSigner).Account().PublicKey().Bytes()) txes = append(txes, registerTx) - voteTx := neoValidatorsInvoker.WithSigners(voters[0]).PrepareInvoke(t, "vote", voters[0].(neotest.SingleSigner).Account().PrivateKey().GetScriptHash(), candidates[0].(neotest.SingleSigner).Account().PrivateKey().PublicKey().Bytes()) + voteTx := neoValidatorsInvoker.WithSigners(voters[0]).PrepareInvoke(t, "vote", voters[0].(neotest.SingleSigner).Account().PrivateKey().GetScriptHash(), candidates[0].(neotest.SingleSigner).Account().PublicKey().Bytes()) txes = append(txes, voteTx) neoValidatorsInvoker.AddNewBlock(t, txes...) for _, tx := range txes { @@ -198,7 +198,7 @@ func TestNEO_Vote(t *testing.T) { require.NoError(t, err) sortedCandidates := make(keys.PublicKeys, validatorsCount) for i := range candidates[:validatorsCount] { - sortedCandidates[i] = candidates[i].(neotest.SingleSigner).Account().PrivateKey().PublicKey() + sortedCandidates[i] = candidates[i].(neotest.SingleSigner).Account().PublicKey() } sort.Sort(sortedCandidates) require.EqualValues(t, sortedCandidates, keys.PublicKeys(pubs)) @@ -259,8 +259,8 @@ func TestNEO_Vote(t *testing.T) { } }) - neoCommitteeInvoker.WithSigners(candidates[0]).Invoke(t, true, "unregisterCandidate", candidates[0].(neotest.SingleSigner).Account().PrivateKey().PublicKey().Bytes()) - neoCommitteeInvoker.WithSigners(voters[0]).Invoke(t, false, "vote", voters[0].(neotest.SingleSigner).Account().PrivateKey().GetScriptHash(), candidates[0].(neotest.SingleSigner).Account().PrivateKey().PublicKey().Bytes()) + neoCommitteeInvoker.WithSigners(candidates[0]).Invoke(t, true, "unregisterCandidate", candidates[0].(neotest.SingleSigner).Account().PublicKey().Bytes()) + neoCommitteeInvoker.WithSigners(voters[0]).Invoke(t, false, "vote", voters[0].(neotest.SingleSigner).Account().PrivateKey().GetScriptHash(), candidates[0].(neotest.SingleSigner).Account().PublicKey().Bytes()) advanceChain(t) @@ -564,9 +564,9 @@ func TestNEO_GetCandidates(t *testing.T) { for i := 0; i < candidatesCount; i++ { transferTx := neoValidatorsInvoker.PrepareInvoke(t, "transfer", e.Validator.ScriptHash(), voters[i].(neotest.SingleSigner).Account().PrivateKey().GetScriptHash(), int64(candidatesCount+1-i)*1000000, nil) txes = append(txes, transferTx) - registerTx := neoValidatorsInvoker.WithSigners(candidates[i]).PrepareInvoke(t, "registerCandidate", candidates[i].(neotest.SingleSigner).Account().PrivateKey().PublicKey().Bytes()) + registerTx := neoValidatorsInvoker.WithSigners(candidates[i]).PrepareInvoke(t, "registerCandidate", candidates[i].(neotest.SingleSigner).Account().PublicKey().Bytes()) txes = append(txes, registerTx) - voteTx := neoValidatorsInvoker.WithSigners(voters[i]).PrepareInvoke(t, "vote", voters[i].(neotest.SingleSigner).Account().PrivateKey().GetScriptHash(), candidates[i].(neotest.SingleSigner).Account().PrivateKey().PublicKey().Bytes()) + voteTx := neoValidatorsInvoker.WithSigners(voters[i]).PrepareInvoke(t, "vote", voters[i].(neotest.SingleSigner).Account().PrivateKey().GetScriptHash(), candidates[i].(neotest.SingleSigner).Account().PublicKey().Bytes()) txes = append(txes, voteTx) } @@ -576,7 +576,7 @@ func TestNEO_GetCandidates(t *testing.T) { } expected := make([]stackitem.Item, candidatesCount) for i := range expected { - pub := candidates[i].(neotest.SingleSigner).Account().PrivateKey().PublicKey().Bytes() + pub := candidates[i].(neotest.SingleSigner).Account().PublicKey().Bytes() v := stackitem.NewBigInteger(big.NewInt(int64(candidatesCount-i+1) * 1000000)) expected[i] = stackitem.NewStruct([]stackitem.Item{ stackitem.NewByteArray(pub), @@ -613,7 +613,7 @@ func TestNEO_GetCandidates(t *testing.T) { checkGetAllCandidates(t, expected) // Block candidate and check it won't be returned from getCandidates and getAllCandidates. - unlucky := candidates[len(candidates)-1].(neotest.SingleSigner).Account().PrivateKey().PublicKey() + unlucky := candidates[len(candidates)-1].(neotest.SingleSigner).Account().PublicKey() policyInvoker.Invoke(t, true, "blockAccount", unlucky.GetScriptHash()) for i := range expected { if bytes.Equal(expected[i].Value().([]stackitem.Item)[0].Value().([]byte), unlucky.Bytes()) { diff --git a/pkg/core/native/native_test/oracle_test.go b/pkg/core/native/native_test/oracle_test.go index dec7ab41d..f7ce224f3 100644 --- a/pkg/core/native/native_test/oracle_test.go +++ b/pkg/core/native/native_test/oracle_test.go @@ -71,8 +71,8 @@ func TestOracle_Request(t *testing.T) { // Designate single Oracle node. oracleNode := e.NewAccount(t) - designationCommitteeInvoker.Invoke(t, stackitem.Null{}, "designateAsRole", int(noderoles.Oracle), []interface{}{oracleNode.(neotest.SingleSigner).Account().PrivateKey().PublicKey().Bytes()}) - err = oracleNode.(neotest.SingleSigner).Account().ConvertMultisig(1, []*keys.PublicKey{oracleNode.(neotest.SingleSigner).Account().PrivateKey().PublicKey()}) + designationCommitteeInvoker.Invoke(t, stackitem.Null{}, "designateAsRole", int(noderoles.Oracle), []interface{}{oracleNode.(neotest.SingleSigner).Account().PublicKey().Bytes()}) + err = oracleNode.(neotest.SingleSigner).Account().ConvertMultisig(1, []*keys.PublicKey{oracleNode.(neotest.SingleSigner).Account().PublicKey()}) require.NoError(t, err) oracleNodeMulti := neotest.NewMultiSigner(oracleNode.(neotest.SingleSigner).Account()) gasCommitteeInvoker.Invoke(t, true, "transfer", gasCommitteeInvoker.CommitteeHash, oracleNodeMulti.ScriptHash(), 100_0000_0000, nil) diff --git a/pkg/neotest/chain/chain.go b/pkg/neotest/chain/chain.go index 1d675687d..4e6de45e0 100644 --- a/pkg/neotest/chain/chain.go +++ b/pkg/neotest/chain/chain.go @@ -58,7 +58,7 @@ var ( func init() { committeeAcc, _ = wallet.NewAccountFromWIF(singleValidatorWIF) - pubs := keys.PublicKeys{committeeAcc.PrivateKey().PublicKey()} + pubs := keys.PublicKeys{committeeAcc.PublicKey()} err := committeeAcc.ConvertMultisig(1, pubs) if err != nil { panic(err) @@ -70,7 +70,7 @@ func init() { pubs = make(keys.PublicKeys, len(accs)) for i := range committeeWIFs { accs[i], _ = wallet.NewAccountFromWIF(committeeWIFs[i]) - pubs[i] = accs[i].PrivateKey().PublicKey() + pubs[i] = accs[i].PublicKey() } // Config entry must contain validators first in a specific order. @@ -86,8 +86,8 @@ func init() { sort.Sort(pubs[:4]) sort.Slice(accs[:4], func(i, j int) bool { - p1 := accs[i].PrivateKey().PublicKey() - p2 := accs[j].PrivateKey().PublicKey() + p1 := accs[i].PublicKey() + p2 := accs[j].PublicKey() return p1.Cmp(p2) == -1 }) for i := range multiValidatorAcc { @@ -102,8 +102,8 @@ func init() { sort.Sort(pubs) sort.Slice(accs, func(i, j int) bool { - p1 := accs[i].PrivateKey().PublicKey() - p2 := accs[j].PrivateKey().PublicKey() + p1 := accs[i].PublicKey() + p2 := accs[j].PublicKey() return p1.Cmp(p2) == -1 }) for i := range multiCommitteeAcc { @@ -141,7 +141,7 @@ func NewSingleWithCustomConfigAndStore(t testing.TB, f func(cfg *config.Protocol Magic: netmode.UnitTestNet, MaxTraceableBlocks: MaxTraceableBlocks, SecondsPerBlock: SecondsPerBlock, - StandbyCommittee: []string{hex.EncodeToString(committeeAcc.PrivateKey().PublicKey().Bytes())}, + StandbyCommittee: []string{hex.EncodeToString(committeeAcc.PublicKey().Bytes())}, ValidatorsCount: 1, VerifyBlocks: true, VerifyTransactions: true, diff --git a/pkg/neotest/signer.go b/pkg/neotest/signer.go index 04020554b..5821e4803 100644 --- a/pkg/neotest/signer.go +++ b/pkg/neotest/signer.go @@ -103,8 +103,8 @@ func NewMultiSigner(accs ...*wallet.Account) MultiSigner { "but only %d accounts were provided", m, len(accs))) } sort.Slice(accs, func(i, j int) bool { - p1 := accs[i].PrivateKey().PublicKey() - p2 := accs[j].PrivateKey().PublicKey() + p1 := accs[i].PublicKey() + p2 := accs[j].PublicKey() return p1.Cmp(p2) == -1 }) for _, acc := range accs { diff --git a/pkg/neotest/signer_test.go b/pkg/neotest/signer_test.go index 3b4f27cc6..0f14a1512 100644 --- a/pkg/neotest/signer_test.go +++ b/pkg/neotest/signer_test.go @@ -28,7 +28,7 @@ func TestMultiSigner(t *testing.T) { require.NoError(t, err) accs[i] = a - pubs[i] = a.PrivateKey().PublicKey() + pubs[i] = a.PublicKey() } sort.Sort(pubs) @@ -40,8 +40,8 @@ func TestMultiSigner(t *testing.T) { s := NewMultiSigner(accs...) for i := range pubs { for j := range accs { - if pub := accs[j].PrivateKey().PublicKey(); pub.Equal(pubs[i]) { - require.Equal(t, pub, s.Single(i).Account().PrivateKey().PublicKey()) + if pub := accs[j].PublicKey(); pub.Equal(pubs[i]) { + require.Equal(t, pub, s.Single(i).Account().PublicKey()) } } } diff --git a/pkg/services/notary/core_test.go b/pkg/services/notary/core_test.go index 3aaeb7837..448f06b14 100644 --- a/pkg/services/notary/core_test.go +++ b/pkg/services/notary/core_test.go @@ -154,7 +154,7 @@ func TestNotary(t *testing.T) { mp1.StopSubscriptions() }) - notaryNodes := []interface{}{acc1.PrivateKey().PublicKey().Bytes(), acc2.PrivateKey().PublicKey().Bytes()} + notaryNodes := []interface{}{acc1.PublicKey().Bytes(), acc2.PrivateKey().PublicKey().Bytes()} designationSuperInvoker.Invoke(t, stackitem.Null{}, "designateAsRole", int64(noderoles.P2PNotary), notaryNodes) @@ -175,7 +175,7 @@ func TestNotary(t *testing.T) { Scopes: transaction.None, }, { - Account: requester.PrivateKey().PublicKey().GetScriptHash(), + Account: requester.PublicKey().GetScriptHash(), Scopes: transaction.None, }, } @@ -222,12 +222,12 @@ func TestNotary(t *testing.T) { var script []byte switch requesters[i].typ { case notary.Signature: - script = requesters[i].accounts[0].PrivateKey().PublicKey().GetVerificationScript() + script = requesters[i].accounts[0].PublicKey().GetVerificationScript() nKeys++ case notary.MultiSignature: pubs := make(keys.PublicKeys, len(requesters[i].accounts)) for j, r := range requesters[i].accounts { - pubs[j] = r.PrivateKey().PublicKey() + pubs[j] = r.PublicKey() } script, err = smartcontract.CreateMultiSigRedeemScript(requesters[i].m, pubs) require.NoError(t, err) @@ -456,7 +456,7 @@ func TestNotary(t *testing.T) { r, _ := checkCompleteStandardRequest(t, 1, false) checkFallbackTxs(t, r, false) // set account back for the next tests - ntr1.UpdateNotaryNodes(keys.PublicKeys{acc1.PrivateKey().PublicKey()}) + ntr1.UpdateNotaryNodes(keys.PublicKeys{acc1.PublicKey()}) // OnNewRequest: signature request for _, i := range []int{1, 2, 3, 10} { @@ -496,7 +496,7 @@ func TestNotary(t *testing.T) { checkMainTx(t, requesters, r, 1, false) checkFallbackTxs(t, r, false) // set account back for the next tests - ntr1.UpdateNotaryNodes(keys.PublicKeys{acc1.PrivateKey().PublicKey()}) + ntr1.UpdateNotaryNodes(keys.PublicKeys{acc1.PublicKey()}) // PostPersist: complete main transaction, signature request setFinalizeWithError(true) @@ -634,7 +634,7 @@ func TestNotary(t *testing.T) { checkMainTx(t, requesters, requests, len(requests), false) checkFallbackTxs(t, requests, false) // set account back for the next tests - ntr1.UpdateNotaryNodes(keys.PublicKeys{acc1.PrivateKey().PublicKey()}) + ntr1.UpdateNotaryNodes(keys.PublicKeys{acc1.PublicKey()}) // OnRequestRemoval: signature request, remove one fallback // check OnNewRequest with finalization error @@ -721,9 +721,9 @@ func TestNotary(t *testing.T) { requester1, _ := wallet.NewAccount() requester2, _ := wallet.NewAccount() amount := int64(100_0000_0000) - gasValidatorInvoker.Invoke(t, true, "transfer", e.Validator.ScriptHash(), bc.GetNotaryContractScriptHash(), amount, []interface{}{requester1.PrivateKey().PublicKey().GetScriptHash(), int64(bc.BlockHeight() + 50)}) + gasValidatorInvoker.Invoke(t, true, "transfer", e.Validator.ScriptHash(), bc.GetNotaryContractScriptHash(), amount, []interface{}{requester1.PublicKey().GetScriptHash(), int64(bc.BlockHeight() + 50)}) e.CheckGASBalance(t, notaryHash, big.NewInt(amount)) - gasValidatorInvoker.Invoke(t, true, "transfer", e.Validator.ScriptHash(), bc.GetNotaryContractScriptHash(), amount, []interface{}{requester2.PrivateKey().PublicKey().GetScriptHash(), int64(bc.BlockHeight() + 50)}) + gasValidatorInvoker.Invoke(t, true, "transfer", e.Validator.ScriptHash(), bc.GetNotaryContractScriptHash(), amount, []interface{}{requester2.PublicKey().GetScriptHash(), int64(bc.BlockHeight() + 50)}) e.CheckGASBalance(t, notaryHash, big.NewInt(2*amount)) // create request for 2 standard signatures => main tx should be completed after the second request is added to the pool diff --git a/pkg/services/notary/node.go b/pkg/services/notary/node.go index ea179baaa..9a7486c56 100644 --- a/pkg/services/notary/node.go +++ b/pkg/services/notary/node.go @@ -15,7 +15,7 @@ func (n *Notary) UpdateNotaryNodes(notaryNodes keys.PublicKeys) { if n.currAccount != nil { for _, node := range notaryNodes { - if node.Equal(n.currAccount.PrivateKey().PublicKey()) { + if node.Equal(n.currAccount.PublicKey()) { return } } diff --git a/pkg/services/notary/node_test.go b/pkg/services/notary/node_test.go index 979c3e848..b1779cd6c 100644 --- a/pkg/services/notary/node_test.go +++ b/pkg/services/notary/node_test.go @@ -44,11 +44,11 @@ func TestUpdateNotaryNodes(t *testing.T) { // currAcc is nil before UpdateNotaryNodes call require.Nil(t, ntr.currAccount) // set account for the first time - ntr.UpdateNotaryNodes(keys.PublicKeys{acc.PrivateKey().PublicKey()}) + ntr.UpdateNotaryNodes(keys.PublicKeys{acc.PublicKey()}) require.Equal(t, acc, ntr.currAccount) t.Run("account is already set", func(t *testing.T) { - ntr.UpdateNotaryNodes(keys.PublicKeys{acc.PrivateKey().PublicKey(), randomKey.PublicKey()}) + ntr.UpdateNotaryNodes(keys.PublicKeys{acc.PublicKey(), randomKey.PublicKey()}) require.Equal(t, acc, ntr.currAccount) }) @@ -57,14 +57,14 @@ func TestUpdateNotaryNodes(t *testing.T) { w, err := wallet.NewWalletFromFile("./testdata/notary1.json") require.NoError(t, err) require.NoError(t, w.Accounts[1].Decrypt("one", w.Scrypt)) - ntr.UpdateNotaryNodes(keys.PublicKeys{w.Accounts[1].PrivateKey().PublicKey()}) + ntr.UpdateNotaryNodes(keys.PublicKeys{w.Accounts[1].PublicKey()}) require.Equal(t, w.Accounts[1], ntr.currAccount) }) t.Run("bad config password", func(t *testing.T) { w, err := wallet.NewWalletFromFile("./testdata/notary1.json") require.NoError(t, err) require.NoError(t, w.Accounts[2].Decrypt("four", w.Scrypt)) - ntr.UpdateNotaryNodes(keys.PublicKeys{w.Accounts[2].PrivateKey().PublicKey()}) + ntr.UpdateNotaryNodes(keys.PublicKeys{w.Accounts[2].PublicKey()}) require.Nil(t, ntr.currAccount) }) }) diff --git a/pkg/services/oracle/oracle_test.go b/pkg/services/oracle/oracle_test.go index f30aebbb1..9cc43bcee 100644 --- a/pkg/services/oracle/oracle_test.go +++ b/pkg/services/oracle/oracle_test.go @@ -122,7 +122,7 @@ func TestCreateResponseTx(t *testing.T) { } cInvoker.Invoke(t, stackitem.Null{}, "requestURL", req.URL, *req.Filter, req.CallbackMethod, req.UserData, int64(req.GasForResponse)) bc.SetOracle(orc) - orc.UpdateOracleNodes(keys.PublicKeys{acc.PrivateKey().PublicKey()}) + orc.UpdateOracleNodes(keys.PublicKeys{acc.PublicKey()}) tx, err = orc.CreateResponseTx(int64(req.GasForResponse), 1, resp) require.NoError(t, err) assert.Equal(t, 166, tx.Size()) @@ -150,7 +150,7 @@ func TestOracle(t *testing.T) { acc1, orc1, m1, ch1 := getTestOracle(t, bc, "./testdata/oracle1.json", "one") acc2, orc2, m2, ch2 := getTestOracle(t, bc, "./testdata/oracle2.json", "two") - oracleNodes := keys.PublicKeys{acc1.PrivateKey().PublicKey(), acc2.PrivateKey().PublicKey()} + oracleNodes := keys.PublicKeys{acc1.PublicKey(), acc2.PrivateKey().PublicKey()} // Must be set in native contract for tx verification. designationSuperInvoker.Invoke(t, stackitem.Null{}, "designateAsRole", int64(roles.Oracle), []interface{}{oracleNodes[0].Bytes(), oracleNodes[1].Bytes()}) @@ -249,10 +249,10 @@ func TestOracle(t *testing.T) { require.Empty(t, ch2) t.Run("InvalidSignature", func(t *testing.T) { - orc1.AddResponse(acc2.PrivateKey().PublicKey(), m2[0].resp.ID, []byte{1, 2, 3}) + orc1.AddResponse(acc2.PublicKey(), m2[0].resp.ID, []byte{1, 2, 3}) require.Empty(t, ch1) }) - orc1.AddResponse(acc2.PrivateKey().PublicKey(), m2[0].resp.ID, m2[0].txSig) + orc1.AddResponse(acc2.PublicKey(), m2[0].resp.ID, m2[0].txSig) checkEmitTx(t, ch1) t.Run("FirstOtherThenMe", func(t *testing.T) { @@ -264,7 +264,7 @@ func TestOracle(t *testing.T) { Result: []byte{1, 2, 3, 4}, } req := checkResp(t, reqID, resp) - orc2.AddResponse(acc1.PrivateKey().PublicKey(), reqID, m1[reqID].txSig) + orc2.AddResponse(acc1.PublicKey(), reqID, m1[reqID].txSig) require.Empty(t, ch2) reqs := map[uint64]*state.OracleRequest{reqID: req} @@ -357,7 +357,7 @@ func TestOracleFull(t *testing.T) { }) designationSuperInvoker.Invoke(t, stackitem.Null{}, "designateAsRole", - int64(roles.Oracle), []interface{}{acc.PrivateKey().PublicKey().Bytes()}) + int64(roles.Oracle), []interface{}{acc.PublicKey().Bytes()}) cs := contracts.GetOracleContractState(t, pathToInternalContracts, validator.ScriptHash(), 0) e.DeployContract(t, &neotest.Contract{ @@ -391,7 +391,7 @@ func TestNotYetRunningOracle(t *testing.T) { t.Cleanup(bc.Close) designationSuperInvoker.Invoke(t, stackitem.Null{}, "designateAsRole", - int64(roles.Oracle), []interface{}{acc.PrivateKey().PublicKey().Bytes()}) + int64(roles.Oracle), []interface{}{acc.PublicKey().Bytes()}) var req state.OracleRequest var reqs = make(map[uint64]*state.OracleRequest) diff --git a/pkg/services/stateroot/service_test.go b/pkg/services/stateroot/service_test.go index 047138c76..92df60ad6 100644 --- a/pkg/services/stateroot/service_test.go +++ b/pkg/services/stateroot/service_test.go @@ -65,13 +65,13 @@ func newMajorityMultisigWithGAS(t *testing.T, n int) (util.Uint160, keys.PublicK accs[i] = acc } sort.Slice(accs, func(i, j int) bool { - pi := accs[i].PrivateKey().PublicKey() - pj := accs[j].PrivateKey().PublicKey() + pi := accs[i].PublicKey() + pj := accs[j].PublicKey() return pi.Cmp(pj) == -1 }) pubs := make(keys.PublicKeys, n) for i := range pubs { - pubs[i] = accs[i].PrivateKey().PublicKey() + pubs[i] = accs[i].PublicKey() } script, err := smartcontract.CreateMajorityMultiSigRedeemScript(pubs) require.NoError(t, err) @@ -126,7 +126,7 @@ func TestStateRoot(t *testing.T) { t.Run("invalid signer", func(t *testing.T) { accInv, err := wallet.NewAccount() require.NoError(t, err) - pubs := keys.PublicKeys{accInv.PrivateKey().PublicKey()} + pubs := keys.PublicKeys{accInv.PublicKey()} require.NoError(t, accInv.ConvertMultisig(1, pubs)) gasValidatorInvoker.Invoke(t, true, "transfer", validator.ScriptHash(), accInv.Contract.ScriptHash(), 1_0000_0000, nil) r, err := bc.GetStateModule().GetStateRoot(1) diff --git a/pkg/services/stateroot/validators.go b/pkg/services/stateroot/validators.go index 5a3ce73a4..c0742d4f6 100644 --- a/pkg/services/stateroot/validators.go +++ b/pkg/services/stateroot/validators.go @@ -91,7 +91,7 @@ func (s *service) signAndSend(r *state.MPTRoot) error { incRoot.Lock() defer incRoot.Unlock() incRoot.root = r - incRoot.addSignature(acc.PrivateKey().PublicKey(), sig) + incRoot.addSignature(acc.PublicKey(), sig) incRoot.reverify(s.Network) s.trySendRoot(incRoot, acc) diff --git a/pkg/wallet/account.go b/pkg/wallet/account.go index c0bc5910a..15df77eac 100644 --- a/pkg/wallet/account.go +++ b/pkg/wallet/account.go @@ -140,7 +140,7 @@ func (a *Account) GetVerificationScript() []byte { if a.Contract != nil { return a.Contract.Script } - return a.PrivateKey().PublicKey().GetVerificationScript() + return a.privateKey.PublicKey().GetVerificationScript() } // Decrypt decrypts the EncryptedWIF with the given passphrase returning error @@ -175,6 +175,15 @@ func (a *Account) PrivateKey() *keys.PrivateKey { return a.privateKey } +// PublicKey returns the public key associated with the private key corresponding to +// the account. It can return nil if account is locked (use CanSign to check). +func (a *Account) PublicKey() *keys.PublicKey { + if !a.CanSign() { + return nil + } + return a.privateKey.PublicKey() +} + // Close cleans up the private key used by Account and disassociates it from // Account. The Account can no longer sign anything after this call, but Decrypt // can make it usable again. diff --git a/pkg/wallet/account_test.go b/pkg/wallet/account_test.go index 238430217..88118176e 100644 --- a/pkg/wallet/account_test.go +++ b/pkg/wallet/account_test.go @@ -105,7 +105,7 @@ func TestContractSignTx(t *testing.T) { require.Error(t, acc2.SignTx(0, tx)) - pubs := keys.PublicKeys{acc.privateKey.PublicKey(), acc2.privateKey.PublicKey()} + pubs := keys.PublicKeys{acc.PublicKey(), acc2.PublicKey()} multiS, err := smartcontract.CreateDefaultMultiSigRedeemScript(pubs) require.NoError(t, err) multiAcc := NewAccountFromPrivateKey(acc.privateKey) @@ -139,6 +139,7 @@ func TestContractSignTx(t *testing.T) { acc2.Locked = true require.False(t, acc2.CanSign()) require.Error(t, acc2.SignTx(0, tx)) // Locked account. + require.Nil(t, acc2.PublicKey()) // Locked account. acc2.Locked = false acc2.Close() @@ -232,7 +233,7 @@ func compareFields(t *testing.T, tk keytestcases.Ktype, acc *Account) { require.Equalf(t, want, have, "expected address %s got %s", want, have) want, have = tk.Wif, acc.privateKey.WIF() require.Equalf(t, want, have, "expected wif %s got %s", want, have) - want, have = tk.PublicKey, hex.EncodeToString(acc.privateKey.PublicKey().Bytes()) + want, have = tk.PublicKey, hex.EncodeToString(acc.PublicKey().Bytes()) require.Equalf(t, want, have, "expected pub key %s got %s", want, have) want, have = tk.PrivateKey, acc.privateKey.String() require.Equalf(t, want, have, "expected priv key %s got %s", want, have)