github.com/koko1123/flow-go-1@v0.29.6/fvm/environment/account_key_updater_test.go (about)

     1  package environment_test
     2  
     3  import (
     4  	"fmt"
     5  	"testing"
     6  	"unicode/utf8"
     7  
     8  	"github.com/fxamacker/cbor/v2"
     9  	"github.com/onflow/atree"
    10  	"github.com/onflow/cadence"
    11  	"github.com/onflow/cadence/runtime"
    12  	"github.com/onflow/cadence/runtime/sema"
    13  	"github.com/stretchr/testify/assert"
    14  	"github.com/stretchr/testify/require"
    15  
    16  	"github.com/onflow/flow-go/crypto"
    17  	"github.com/onflow/flow-go/crypto/hash"
    18  	"github.com/koko1123/flow-go-1/fvm/environment"
    19  	"github.com/koko1123/flow-go-1/fvm/errors"
    20  	"github.com/koko1123/flow-go-1/fvm/tracing"
    21  	"github.com/koko1123/flow-go-1/model/flow"
    22  )
    23  
    24  func TestAddEncodedAccountKey_error_handling_produces_valid_utf8(t *testing.T) {
    25  
    26  	akh := environment.NewAccountKeyUpdater(
    27  		tracing.NewTracerSpan(),
    28  		nil,
    29  		FakeAccounts{},
    30  		nil,
    31  		nil)
    32  
    33  	address := cadence.BytesToAddress([]byte{1, 2, 3, 4})
    34  
    35  	// emulate encoded public key (which comes as a user input)
    36  	// containing bytes which are invalid UTF8
    37  
    38  	invalidEncodedKey := make([]byte, 64)
    39  	invalidUTF8 := []byte{0xc3, 0x28}
    40  	copy(invalidUTF8, invalidEncodedKey)
    41  	accountPublicKey := FakePublicKey{data: invalidEncodedKey}.toAccountPublicKey()
    42  
    43  	encodedPublicKey, err := flow.EncodeRuntimeAccountPublicKey(accountPublicKey)
    44  	require.NoError(t, err)
    45  
    46  	err = akh.InternalAddEncodedAccountKey(
    47  		runtime.Address(address),
    48  		encodedPublicKey)
    49  	require.Error(t, err)
    50  
    51  	require.True(t, errors.IsValueError(err))
    52  
    53  	errorString := err.Error()
    54  	assert.True(t, utf8.ValidString(errorString))
    55  
    56  	// check if they can encoded and decoded using CBOR
    57  	marshalledBytes, err := cbor.Marshal(errorString)
    58  	require.NoError(t, err)
    59  
    60  	var unmarshalledString string
    61  
    62  	err = cbor.Unmarshal(marshalledBytes, &unmarshalledString)
    63  	require.NoError(t, err)
    64  
    65  	require.Equal(t, errorString, unmarshalledString)
    66  }
    67  
    68  func TestNewAccountKey_error_handling_produces_valid_utf8_and_sign_algo(t *testing.T) {
    69  
    70  	invalidSignAlgo := runtime.SignatureAlgorithm(254)
    71  	publicKey := &runtime.PublicKey{
    72  		PublicKey: nil,
    73  		SignAlgo:  invalidSignAlgo,
    74  	}
    75  
    76  	_, err := environment.NewAccountPublicKey(
    77  		publicKey,
    78  		sema.HashAlgorithmSHA2_384,
    79  		0,
    80  		0)
    81  
    82  	require.True(t, errors.IsValueError(err))
    83  
    84  	require.Contains(t, err.Error(), fmt.Sprintf("%d", invalidSignAlgo))
    85  
    86  	errorString := err.Error()
    87  	assert.True(t, utf8.ValidString(errorString))
    88  
    89  	// check if they can encoded and decoded using CBOR
    90  	marshalledBytes, err := cbor.Marshal(errorString)
    91  	require.NoError(t, err)
    92  
    93  	var unmarshalledString string
    94  
    95  	err = cbor.Unmarshal(marshalledBytes, &unmarshalledString)
    96  	require.NoError(t, err)
    97  
    98  	require.Equal(t, errorString, unmarshalledString)
    99  }
   100  
   101  func TestNewAccountKey_error_handling_produces_valid_utf8_and_hash_algo(t *testing.T) {
   102  
   103  	publicKey := &runtime.PublicKey{
   104  		PublicKey: nil,
   105  		SignAlgo:  runtime.SignatureAlgorithmECDSA_P256,
   106  	}
   107  
   108  	invalidHashAlgo := sema.HashAlgorithm(112)
   109  
   110  	_, err := environment.NewAccountPublicKey(publicKey, invalidHashAlgo, 0, 0)
   111  
   112  	require.True(t, errors.IsValueError(err))
   113  
   114  	require.Contains(t, err.Error(), fmt.Sprintf("%d", invalidHashAlgo))
   115  
   116  	errorString := err.Error()
   117  	assert.True(t, utf8.ValidString(errorString))
   118  
   119  	// check if they can encoded and decoded using CBOR
   120  	marshalledBytes, err := cbor.Marshal(errorString)
   121  	require.NoError(t, err)
   122  
   123  	var unmarshalledString string
   124  
   125  	err = cbor.Unmarshal(marshalledBytes, &unmarshalledString)
   126  	require.NoError(t, err)
   127  
   128  	require.Equal(t, errorString, unmarshalledString)
   129  }
   130  
   131  func TestNewAccountKey_error_handling_produces_valid_utf8(t *testing.T) {
   132  
   133  	publicKey := &runtime.PublicKey{
   134  		PublicKey: []byte{0xc3, 0x28}, // some invalid UTF8
   135  		SignAlgo:  runtime.SignatureAlgorithmECDSA_P256,
   136  	}
   137  
   138  	_, err := environment.NewAccountPublicKey(
   139  		publicKey,
   140  		runtime.HashAlgorithmSHA2_256,
   141  		0,
   142  		0)
   143  
   144  	require.True(t, errors.IsValueError(err))
   145  
   146  	errorString := err.Error()
   147  	assert.True(t, utf8.ValidString(errorString))
   148  
   149  	// check if they can encoded and decoded using CBOR
   150  	marshalledBytes, err := cbor.Marshal(errorString)
   151  	require.NoError(t, err)
   152  
   153  	var unmarshalledString string
   154  
   155  	err = cbor.Unmarshal(marshalledBytes, &unmarshalledString)
   156  	require.NoError(t, err)
   157  
   158  	require.Equal(t, errorString, unmarshalledString)
   159  }
   160  
   161  type FakePublicKey struct {
   162  	data []byte
   163  }
   164  
   165  var _ crypto.PublicKey = &FakePublicKey{}
   166  
   167  func (f FakePublicKey) toAccountPublicKey() flow.AccountPublicKey {
   168  	return flow.AccountPublicKey{
   169  		Index:     1,
   170  		PublicKey: f,
   171  		SignAlgo:  crypto.ECDSASecp256k1,
   172  		HashAlgo:  hash.SHA3_256,
   173  		SeqNumber: 0,
   174  		Weight:    1000,
   175  		Revoked:   false,
   176  	}
   177  }
   178  
   179  func (f FakePublicKey) Encode() []byte {
   180  	return f.data
   181  }
   182  
   183  func (f FakePublicKey) Algorithm() crypto.SigningAlgorithm { return crypto.ECDSASecp256k1 }
   184  func (f FakePublicKey) Size() int                          { return 0 }
   185  func (f FakePublicKey) String() string                     { return "" }
   186  func (f FakePublicKey) Verify(_ crypto.Signature, _ []byte, _ hash.Hasher) (bool, error) {
   187  	return false, nil
   188  }
   189  func (f FakePublicKey) EncodeCompressed() []byte         { return nil }
   190  func (f FakePublicKey) Equals(key crypto.PublicKey) bool { return false }
   191  
   192  type FakeAccounts struct {
   193  	keyCount uint64
   194  }
   195  
   196  var _ environment.Accounts = &FakeAccounts{}
   197  
   198  func (f FakeAccounts) Exists(address flow.Address) (bool, error)       { return true, nil }
   199  func (f FakeAccounts) Get(address flow.Address) (*flow.Account, error) { return &flow.Account{}, nil }
   200  func (f FakeAccounts) GetPublicKeyCount(_ flow.Address) (uint64, error) {
   201  	return f.keyCount, nil
   202  }
   203  func (f FakeAccounts) AppendPublicKey(_ flow.Address, _ flow.AccountPublicKey) error { return nil }
   204  func (f FakeAccounts) GetPublicKey(address flow.Address, keyIndex uint64) (flow.AccountPublicKey, error) {
   205  	if keyIndex >= f.keyCount {
   206  		return flow.AccountPublicKey{}, errors.NewAccountPublicKeyNotFoundError(address, keyIndex)
   207  	}
   208  	return FakePublicKey{}.toAccountPublicKey(), nil
   209  }
   210  
   211  func (f FakeAccounts) SetPublicKey(_ flow.Address, _ uint64, _ flow.AccountPublicKey) ([]byte, error) {
   212  	return nil, nil
   213  }
   214  func (f FakeAccounts) GetContractNames(_ flow.Address) ([]string, error)             { return nil, nil }
   215  func (f FakeAccounts) GetContract(_ string, _ flow.Address) ([]byte, error)          { return nil, nil }
   216  func (f FakeAccounts) ContractExists(_ string, _ flow.Address) (bool, error)         { return false, nil }
   217  func (f FakeAccounts) SetContract(_ string, _ flow.Address, _ []byte) error          { return nil }
   218  func (f FakeAccounts) DeleteContract(_ string, _ flow.Address) error                 { return nil }
   219  func (f FakeAccounts) Create(_ []flow.AccountPublicKey, _ flow.Address) error        { return nil }
   220  func (f FakeAccounts) GetValue(_ flow.Address, _ string) (flow.RegisterValue, error) { return nil, nil }
   221  func (f FakeAccounts) CheckAccountNotFrozen(_ flow.Address) error                    { return nil }
   222  func (f FakeAccounts) GetStorageUsed(_ flow.Address) (uint64, error)                 { return 0, nil }
   223  func (f FakeAccounts) SetValue(_ flow.Address, _ string, _ []byte) error             { return nil }
   224  func (f FakeAccounts) AllocateStorageIndex(_ flow.Address) (atree.StorageIndex, error) {
   225  	return atree.StorageIndex{}, nil
   226  }
   227  func (f FakeAccounts) SetAccountFrozen(_ flow.Address, _ bool) error { return nil }