github.com/ConsenSys/Quorum@v20.10.0+incompatible/accounts/pluggable/wallet_test.go (about)

     1  package pluggable
     2  
     3  import (
     4  	"math/big"
     5  	"math/rand"
     6  	"testing"
     7  
     8  	"github.com/ethereum/go-ethereum/accounts"
     9  	"github.com/ethereum/go-ethereum/accounts/pluggable/internal/testutils/mock_plugin"
    10  	"github.com/ethereum/go-ethereum/common"
    11  	"github.com/ethereum/go-ethereum/core/types"
    12  	"github.com/ethereum/go-ethereum/crypto"
    13  	"github.com/golang/mock/gomock"
    14  	"github.com/stretchr/testify/assert"
    15  	"github.com/stretchr/testify/require"
    16  )
    17  
    18  var (
    19  	scheme = "scheme"
    20  
    21  	wltUrl = accounts.URL{
    22  		Scheme: scheme,
    23  		Path:   "uripath",
    24  	}
    25  
    26  	acct1 = accounts.Account{
    27  		Address: common.HexToAddress("0x4d6d744b6da435b5bbdde2526dc20e9a41cb72e5"),
    28  		URL:     wltUrl,
    29  	}
    30  
    31  	acct2 = accounts.Account{
    32  		Address: common.HexToAddress("0x2332f90a329c2c55ba120b1449d36a144d1f9fe4"),
    33  		URL:     accounts.URL{Scheme: scheme, Path: "path/to/file2.json"},
    34  	}
    35  	acct3 = accounts.Account{
    36  		Address: common.HexToAddress("0x992d7a8fca612c963796ecbfe78b300370b9545a"),
    37  		URL:     accounts.URL{Scheme: scheme, Path: "path/to/file3.json"},
    38  	}
    39  	acct4 = accounts.Account{
    40  		Address: common.HexToAddress("0x39ac8f3ae3681b4422fdf808ae18ba4365e37da8"),
    41  		URL:     accounts.URL{Scheme: scheme, Path: "path/to/file4.json"},
    42  	}
    43  )
    44  
    45  func validWallet(m *mock_plugin.MockService) *wallet {
    46  	return &wallet{
    47  		url:           wltUrl,
    48  		pluginService: m,
    49  	}
    50  }
    51  
    52  func TestWallet_Url(t *testing.T) {
    53  	w := validWallet(nil)
    54  	got := w.URL()
    55  	assert.Equal(t, wltUrl, got)
    56  }
    57  
    58  func TestWallet_Status(t *testing.T) {
    59  	ctrl := gomock.NewController(t)
    60  	defer ctrl.Finish()
    61  
    62  	want := "status"
    63  
    64  	mockClient := mock_plugin.NewMockService(ctrl)
    65  	mockClient.
    66  		EXPECT().
    67  		Status(gomock.Any()).
    68  		Return(want, nil)
    69  
    70  	w := validWallet(mockClient)
    71  	status, err := w.Status()
    72  
    73  	assert.NoError(t, err)
    74  	assert.Equal(t, want, status)
    75  }
    76  
    77  func TestWallet_Open(t *testing.T) {
    78  	ctrl := gomock.NewController(t)
    79  	defer ctrl.Finish()
    80  
    81  	mockClient := mock_plugin.NewMockService(ctrl)
    82  	mockClient.
    83  		EXPECT().
    84  		Open(gomock.Any(), "pwd").
    85  		Return(nil)
    86  
    87  	w := validWallet(mockClient)
    88  	err := w.Open("pwd")
    89  
    90  	assert.NoError(t, err)
    91  }
    92  
    93  func TestWallet_Close(t *testing.T) {
    94  	ctrl := gomock.NewController(t)
    95  	defer ctrl.Finish()
    96  
    97  	mockClient := mock_plugin.NewMockService(ctrl)
    98  	mockClient.
    99  		EXPECT().
   100  		Close(gomock.Any()).
   101  		Return(nil)
   102  
   103  	w := validWallet(mockClient)
   104  	err := w.Close()
   105  
   106  	assert.NoError(t, err)
   107  }
   108  
   109  func TestWallet_Accounts(t *testing.T) {
   110  	ctrl := gomock.NewController(t)
   111  	defer ctrl.Finish()
   112  
   113  	want := []accounts.Account{acct1, acct2, acct3, acct4}
   114  
   115  	mockClient := mock_plugin.NewMockService(ctrl)
   116  	mockClient.
   117  		EXPECT().
   118  		Accounts(gomock.Any()).
   119  		Return(want)
   120  
   121  	w := validWallet(mockClient)
   122  	got := w.Accounts()
   123  
   124  	assert.Equal(t, want, got)
   125  }
   126  
   127  func TestWallet_Contains(t *testing.T) {
   128  	ctrl := gomock.NewController(t)
   129  	defer ctrl.Finish()
   130  
   131  	mockClient := mock_plugin.NewMockService(ctrl)
   132  	mockClient.
   133  		EXPECT().
   134  		Contains(gomock.Any(), acct1).
   135  		Return(true)
   136  
   137  	w := validWallet(mockClient)
   138  	got := w.Contains(acct1)
   139  
   140  	assert.True(t, got)
   141  }
   142  
   143  func TestWallet_Derive(t *testing.T) {
   144  	w := validWallet(nil)
   145  	_, err := w.Derive(accounts.DerivationPath{}, true)
   146  	if assert.Error(t, err) {
   147  		assert.Equal(t, accounts.ErrNotSupported, err)
   148  	}
   149  }
   150  
   151  func TestWallet_SelfDerive(t *testing.T) {
   152  	w := validWallet(nil)
   153  	// does nothing
   154  	w.SelfDerive([]accounts.DerivationPath{}, nil)
   155  }
   156  
   157  func TestWallet_SignData(t *testing.T) {
   158  	ctrl := gomock.NewController(t)
   159  	defer ctrl.Finish()
   160  
   161  	toSign := []byte("somedata")
   162  	want := []byte("signeddata")
   163  
   164  	mockClient := mock_plugin.NewMockService(ctrl)
   165  	mockClient.
   166  		EXPECT().
   167  		Sign(gomock.Any(), acct1, crypto.Keccak256(toSign)).
   168  		Return(want, nil)
   169  
   170  	w := validWallet(mockClient)
   171  	got, err := w.SignData(acct1, "", toSign)
   172  
   173  	assert.NoError(t, err)
   174  	assert.Equal(t, want, got)
   175  }
   176  
   177  func TestWallet_SignDataWithPassphrase(t *testing.T) {
   178  	ctrl := gomock.NewController(t)
   179  	defer ctrl.Finish()
   180  
   181  	toSign := []byte("somedata")
   182  	want := []byte("signeddata")
   183  
   184  	mockClient := mock_plugin.NewMockService(ctrl)
   185  	mockClient.
   186  		EXPECT().
   187  		UnlockAndSign(gomock.Any(), acct1, crypto.Keccak256(toSign), "pwd").
   188  		Return(want, nil)
   189  
   190  	w := validWallet(mockClient)
   191  	got, err := w.SignDataWithPassphrase(acct1, "pwd", "", toSign)
   192  
   193  	assert.NoError(t, err)
   194  	assert.Equal(t, want, got)
   195  }
   196  
   197  func TestWallet_SignText(t *testing.T) {
   198  	ctrl := gomock.NewController(t)
   199  	defer ctrl.Finish()
   200  
   201  	toSign := []byte("somedata")
   202  	want := []byte("signeddata")
   203  
   204  	mockClient := mock_plugin.NewMockService(ctrl)
   205  	mockClient.
   206  		EXPECT().
   207  		Sign(gomock.Any(), acct1, accounts.TextHash(toSign)).
   208  		Return(want, nil)
   209  
   210  	w := validWallet(mockClient)
   211  	got, err := w.SignText(acct1, toSign)
   212  
   213  	assert.NoError(t, err)
   214  	assert.Equal(t, want, got)
   215  }
   216  
   217  func TestWallet_SignTextWithPassphrase(t *testing.T) {
   218  	ctrl := gomock.NewController(t)
   219  	defer ctrl.Finish()
   220  
   221  	toSign := []byte("somedata")
   222  	want := []byte("signeddata")
   223  
   224  	mockClient := mock_plugin.NewMockService(ctrl)
   225  	mockClient.
   226  		EXPECT().
   227  		UnlockAndSign(gomock.Any(), acct1, accounts.TextHash(toSign), "pwd").
   228  		Return(want, nil)
   229  
   230  	w := validWallet(mockClient)
   231  	got, err := w.SignTextWithPassphrase(acct1, "pwd", toSign)
   232  
   233  	assert.NoError(t, err)
   234  	assert.Equal(t, want, got)
   235  }
   236  
   237  func TestWallet_SignTx(t *testing.T) {
   238  	ctrl := gomock.NewController(t)
   239  	defer ctrl.Finish()
   240  
   241  	tests := []struct {
   242  		name      string
   243  		isPrivate bool
   244  		chainID   *big.Int
   245  		signer    types.Signer
   246  	}{
   247  		{
   248  			name:      "Public EIP155 tx",
   249  			isPrivate: false,
   250  			chainID:   big.NewInt(20),
   251  			signer:    types.NewEIP155Signer(big.NewInt(20)),
   252  		},
   253  		{
   254  			name:      "Public Homestead tx",
   255  			isPrivate: false,
   256  			chainID:   nil,
   257  			signer:    types.HomesteadSigner{},
   258  		},
   259  		{
   260  			name:      "Private tx",
   261  			isPrivate: true,
   262  			chainID:   nil,
   263  			signer:    types.QuorumPrivateTxSigner{},
   264  		},
   265  	}
   266  
   267  	toSign := types.NewTransaction(
   268  		1,
   269  		common.HexToAddress("0x2332f90a329c2c55ba120b1449d36a144d1f9fe4"),
   270  		big.NewInt(1),
   271  		0,
   272  		big.NewInt(1),
   273  		nil,
   274  	)
   275  
   276  	for _, tt := range tests {
   277  		t.Run(tt.name, func(t *testing.T) {
   278  			if tt.isPrivate {
   279  				toSign.SetPrivate()
   280  			}
   281  
   282  			hashToSign := tt.signer.Hash(toSign)
   283  
   284  			mockSig := make([]byte, 65)
   285  			rand.Read(mockSig)
   286  
   287  			mockClient := mock_plugin.NewMockService(ctrl)
   288  			mockClient.
   289  				EXPECT().
   290  				Sign(gomock.Any(), acct1, hashToSign.Bytes()).
   291  				Return(mockSig, nil)
   292  
   293  			w := validWallet(mockClient)
   294  			got, err := w.SignTx(acct1, toSign, tt.chainID)
   295  			require.NoError(t, err)
   296  
   297  			gotV, gotR, gotS := got.RawSignatureValues()
   298  
   299  			wantR, wantS, wantV, err := tt.signer.SignatureValues(&types.Transaction{}, mockSig) // tx param is unused by method
   300  			require.NoError(t, err)
   301  
   302  			// assert the correct signature is added to the tx
   303  			assert.Equal(t, wantV, gotV)
   304  			assert.Equal(t, wantR, gotR)
   305  			assert.Equal(t, wantS, gotS)
   306  
   307  			// assert the rest of the tx is unchanged
   308  			assert.Equal(t, toSign.Nonce(), got.Nonce())
   309  			assert.Equal(t, toSign.GasPrice(), got.GasPrice())
   310  			assert.Equal(t, toSign.Gas(), got.Gas())
   311  			assert.Equal(t, toSign.To(), got.To())
   312  			assert.Equal(t, toSign.Value(), got.Value())
   313  			assert.Equal(t, toSign.Data(), got.Data())
   314  		})
   315  	}
   316  }
   317  
   318  func TestWallet_SignTxWithPassphrase(t *testing.T) {
   319  	ctrl := gomock.NewController(t)
   320  	defer ctrl.Finish()
   321  
   322  	tests := []struct {
   323  		name      string
   324  		isPrivate bool
   325  		chainID   *big.Int
   326  		signer    types.Signer
   327  	}{
   328  		{
   329  			name:      "Public EIP155 tx",
   330  			isPrivate: false,
   331  			chainID:   big.NewInt(20),
   332  			signer:    types.NewEIP155Signer(big.NewInt(20)),
   333  		},
   334  		{
   335  			name:      "Public Homestead tx",
   336  			isPrivate: false,
   337  			chainID:   nil,
   338  			signer:    types.HomesteadSigner{},
   339  		},
   340  		{
   341  			name:      "Private tx",
   342  			isPrivate: true,
   343  			chainID:   nil,
   344  			signer:    types.QuorumPrivateTxSigner{},
   345  		},
   346  	}
   347  
   348  	toSign := types.NewTransaction(
   349  		1,
   350  		common.HexToAddress("0x2332f90a329c2c55ba120b1449d36a144d1f9fe4"),
   351  		big.NewInt(1),
   352  		0,
   353  		big.NewInt(1),
   354  		nil,
   355  	)
   356  
   357  	for _, tt := range tests {
   358  		t.Run(tt.name, func(t *testing.T) {
   359  			if tt.isPrivate {
   360  				toSign.SetPrivate()
   361  			}
   362  
   363  			hashToSign := tt.signer.Hash(toSign)
   364  
   365  			mockSig := make([]byte, 65)
   366  			rand.Read(mockSig)
   367  
   368  			mockClient := mock_plugin.NewMockService(ctrl)
   369  			mockClient.
   370  				EXPECT().
   371  				UnlockAndSign(gomock.Any(), acct1, hashToSign.Bytes(), "pwd").
   372  				Return(mockSig, nil)
   373  
   374  			w := validWallet(mockClient)
   375  			got, err := w.SignTxWithPassphrase(acct1, "pwd", toSign, tt.chainID)
   376  			require.NoError(t, err)
   377  
   378  			gotV, gotR, gotS := got.RawSignatureValues()
   379  
   380  			wantR, wantS, wantV, err := tt.signer.SignatureValues(&types.Transaction{}, mockSig) // tx param is unused by method
   381  			require.NoError(t, err)
   382  
   383  			// assert the correct signature is added to the tx
   384  			assert.Equal(t, wantV, gotV)
   385  			assert.Equal(t, wantR, gotR)
   386  			assert.Equal(t, wantS, gotS)
   387  
   388  			// assert the rest of the tx is unchanged
   389  			assert.Equal(t, toSign.Nonce(), got.Nonce())
   390  			assert.Equal(t, toSign.GasPrice(), got.GasPrice())
   391  			assert.Equal(t, toSign.Gas(), got.Gas())
   392  			assert.Equal(t, toSign.To(), got.To())
   393  			assert.Equal(t, toSign.Value(), got.Value())
   394  			assert.Equal(t, toSign.Data(), got.Data())
   395  		})
   396  	}
   397  }