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 }