From 778d76e4a8c57b76c0ad58936f92a854c15486cd Mon Sep 17 00:00:00 2001 From: JayT106 Date: Thu, 5 Sep 2024 21:52:58 -0400 Subject: [PATCH] feat: missing GKMSSigner feature (#78) Co-authored-by: Calvin Lau <38898718+calvinaco@users.noreply.github.com> --- Cargo.lock | 518 +++++++++++++++++- core/bin/zksync_server/src/node_builder.rs | 22 +- core/lib/config/src/configs/eth_sender.rs | 10 + core/lib/config/src/testonly.rs | 3 +- core/lib/env_config/src/eth_sender.rs | 5 +- core/lib/eth_client/src/clients/http/mod.rs | 2 +- .../eth_client/src/clients/http/signing.rs | 35 +- core/lib/eth_client/src/clients/mod.rs | 2 +- core/lib/eth_signer/Cargo.toml | 8 + core/lib/eth_signer/src/g_kms_signer.rs | 161 ++++++ core/lib/eth_signer/src/lib.rs | 1 + core/lib/eth_signer/src/raw_ethereum_tx.rs | 4 + core/lib/protobuf_config/src/eth.rs | 23 + .../src/proto/config/eth_sender.proto | 12 +- .../layers/pk_signing_eth_client.rs | 122 ++++- etc/env/base/eth_sender.toml | 2 + 16 files changed, 870 insertions(+), 60 deletions(-) create mode 100644 core/lib/eth_signer/src/g_kms_signer.rs diff --git a/Cargo.lock b/Cargo.lock index 7e4cad34c..b4375ddac 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -542,6 +542,17 @@ dependencies = [ "winapi", ] +[[package]] +name = "auto_impl" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c87f3f15e7794432337fc718554eaa4dc8f04c9677a950ffe366f20a162ae42" +dependencies = [ + "proc-macro2 1.0.86", + "quote 1.0.37", + "syn 2.0.77", +] + [[package]] name = "autocfg" version = "1.3.0" @@ -575,6 +586,34 @@ dependencies = [ "paste", ] +[[package]] +name = "axum" +version = "0.6.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b829e4e32b91e643de6eafe82b1d90675f5874230191a4ffbc1b336dec4d6bf" +dependencies = [ + "async-trait", + "axum-core 0.3.4", + "bitflags 1.3.2", + "bytes", + "futures-util", + "http 0.2.12", + "http-body 0.4.6", + "hyper 0.14.30", + "itoa", + "matchit", + "memchr", + "mime", + "percent-encoding", + "pin-project-lite", + "rustversion", + "serde", + "sync_wrapper 0.1.2", + "tower 0.4.13", + "tower-layer", + "tower-service", +] + [[package]] name = "axum" version = "0.7.6" @@ -582,7 +621,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f43644eed690f5374f1af436ecd6aea01cd201f6fbdf0178adaf6907afb2cec" dependencies = [ "async-trait", - "axum-core", + "axum-core 0.4.4", "bytes", "futures-util", "http 1.1.0", @@ -610,6 +649,23 @@ dependencies = [ "tracing", ] +[[package]] +name = "axum-core" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "759fa577a247914fd3f7f76d62972792636412fbfd634cd452f6a385a74d2d2c" +dependencies = [ + "async-trait", + "bytes", + "futures-util", + "http 0.2.12", + "http-body 0.4.6", + "mime", + "rustversion", + "tower-layer", + "tower-service", +] + [[package]] name = "axum-core" version = "0.4.4" @@ -711,6 +767,12 @@ dependencies = [ "regex", ] +[[package]] +name = "bech32" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d86b93f97252c47b41663388e6d155714a9d0c398b99f1005cbc5f978b29f445" + [[package]] name = "beef" version = "0.5.2" @@ -1059,6 +1121,7 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bf88ba1141d185c399bee5288d850d63b8369520c1eafc32a0430b5b6c287bf4" dependencies = [ + "sha2 0.10.8", "tinyvec", ] @@ -1119,6 +1182,9 @@ name = "bytes" version = "1.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "428d9aa8fbc0670b7b8d6030a7fadd0f86151cae55e4dbbece15f3780a3dfaf3" +dependencies = [ + "serde", +] [[package]] name = "bytesize" @@ -1510,6 +1576,58 @@ dependencies = [ "indexmap 1.9.3", ] +[[package]] +name = "coins-bip32" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b6be4a5df2098cd811f3194f64ddb96c267606bffd9689ac7b0160097b01ad3" +dependencies = [ + "bs58", + "coins-core", + "digest 0.10.7", + "hmac 0.12.1", + "k256 0.13.4", + "serde", + "sha2 0.10.8", + "thiserror", +] + +[[package]] +name = "coins-bip39" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3db8fba409ce3dc04f7d804074039eb68b960b0829161f8e06c95fea3f122528" +dependencies = [ + "bitvec", + "coins-bip32", + "hmac 0.12.1", + "once_cell", + "pbkdf2 0.12.2", + "rand 0.8.5", + "sha2 0.10.8", + "thiserror", +] + +[[package]] +name = "coins-core" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5286a0843c21f8367f7be734f89df9b822e0321d8bcce8d6e735aadff7d74979" +dependencies = [ + "base64 0.21.7", + "bech32", + "bs58", + "digest 0.10.7", + "generic-array", + "hex", + "ripemd", + "serde", + "serde_derive", + "sha2 0.10.8", + "sha3 0.10.8", + "thiserror", +] + [[package]] name = "colorchoice" version = "1.0.2" @@ -1562,6 +1680,19 @@ dependencies = [ "compile-fmt", ] +[[package]] +name = "const-hex" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94fb8a24a26d37e1ffd45343323dc9fe6654ceea44c12f2fcb3d7ac29e610bc6" +dependencies = [ + "cfg-if", + "cpufeatures", + "hex", + "proptest", + "serde", +] + [[package]] name = "const-oid" version = "0.9.6" @@ -1988,7 +2119,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef552e6f588e446098f6ba40d89ac146c8c7b64aade83c051ee00bb5d2bc18d" dependencies = [ "serde", - "uuid", + "uuid 1.10.0", ] [[package]] @@ -2365,6 +2496,28 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "eth-keystore" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fda3bf123be441da5260717e0661c25a2fd9cb2b2c1d20bf2e05580047158ab" +dependencies = [ + "aes", + "ctr", + "digest 0.10.7", + "hex", + "hmac 0.12.1", + "pbkdf2 0.11.0", + "rand 0.8.5", + "scrypt", + "serde", + "serde_json", + "sha2 0.10.8", + "sha3 0.10.8", + "thiserror", + "uuid 0.8.2", +] + [[package]] name = "ethabi" version = "18.0.0" @@ -2390,8 +2543,10 @@ checksum = "c22d4b5885b6aa2fe5e8b9329fb8d232bf739e434e6b87347c63bdd00c120f60" dependencies = [ "crunchy", "fixed-hash", + "impl-codec", "impl-rlp", "impl-serde", + "scale-info", "tiny-keccak 2.0.2", ] @@ -2403,12 +2558,60 @@ checksum = "02d215cbf040552efcbe99a38372fe80ab9d00268e20012b79fcd0f073edd8ee" dependencies = [ "ethbloom", "fixed-hash", + "impl-codec", "impl-rlp", "impl-serde", "primitive-types", + "scale-info", "uint", ] +[[package]] +name = "ethers-core" +version = "2.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82d80cc6ad30b14a48ab786523af33b37f28a8623fc06afd55324816ef18fb1f" +dependencies = [ + "arrayvec 0.7.6", + "bytes", + "chrono", + "const-hex", + "elliptic-curve 0.13.8", + "ethabi", + "generic-array", + "k256 0.13.4", + "num_enum 0.7.3", + "open-fastrlp", + "rand 0.8.5", + "rlp", + "serde", + "serde_json", + "strum", + "tempfile", + "thiserror", + "tiny-keccak 2.0.2", + "unicode-xid 0.2.6", +] + +[[package]] +name = "ethers-signers" +version = "2.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "228875491c782ad851773b652dd8ecac62cda8571d3bc32a5853644dd26766c2" +dependencies = [ + "async-trait", + "coins-bip32", + "coins-bip39", + "const-hex", + "elliptic-curve 0.13.8", + "eth-keystore", + "ethers-core", + "rand 0.8.5", + "sha2 0.10.8", + "thiserror", + "tracing", +] + [[package]] name = "event-listener" version = "2.5.3" @@ -2926,8 +3129,8 @@ checksum = "1112c453c2e155b3e683204ffff52bcc6d6495d04b68d9e90cd24161270c5058" dependencies = [ "async-trait", "base64 0.21.7", - "google-cloud-metadata", - "google-cloud-token", + "google-cloud-metadata 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "google-cloud-token 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "home", "jsonwebtoken", "reqwest 0.12.7", @@ -2940,6 +3143,72 @@ dependencies = [ "urlencoding", ] +[[package]] +name = "google-cloud-auth" +version = "0.16.0" +source = "git+https://github.com/yoshidan/google-cloud-rust.git?tag=v20240627#8f387a13309707c493d2e581961ee5b0f20631fc" +dependencies = [ + "async-trait", + "base64 0.21.7", + "google-cloud-metadata 0.5.0 (git+https://github.com/yoshidan/google-cloud-rust.git?tag=v20240627)", + "google-cloud-token 0.1.2 (git+https://github.com/yoshidan/google-cloud-rust.git?tag=v20240627)", + "home", + "jsonwebtoken", + "reqwest 0.12.7", + "serde", + "serde_json", + "thiserror", + "time", + "tokio", + "tracing", + "urlencoding", +] + +[[package]] +name = "google-cloud-gax" +version = "0.18.0" +source = "git+https://github.com/yoshidan/google-cloud-rust.git?tag=v20240627#8f387a13309707c493d2e581961ee5b0f20631fc" +dependencies = [ + "google-cloud-token 0.1.2 (git+https://github.com/yoshidan/google-cloud-rust.git?tag=v20240627)", + "http 0.2.12", + "thiserror", + "tokio", + "tokio-retry", + "tonic 0.11.0", + "tower 0.4.13", + "tracing", +] + +[[package]] +name = "google-cloud-googleapis" +version = "0.14.0" +source = "git+https://github.com/yoshidan/google-cloud-rust.git?tag=v20240627#8f387a13309707c493d2e581961ee5b0f20631fc" +dependencies = [ + "prost 0.12.6", + "prost-types", + "tonic 0.11.0", +] + +[[package]] +name = "google-cloud-kms" +version = "0.3.0" +source = "git+https://github.com/yoshidan/google-cloud-rust.git?tag=v20240627#8f387a13309707c493d2e581961ee5b0f20631fc" +dependencies = [ + "async-trait", + "ethers-core", + "ethers-signers", + "google-cloud-auth 0.16.0 (git+https://github.com/yoshidan/google-cloud-rust.git?tag=v20240627)", + "google-cloud-gax", + "google-cloud-googleapis", + "google-cloud-token 0.1.2 (git+https://github.com/yoshidan/google-cloud-rust.git?tag=v20240627)", + "k256 0.13.4", + "prost-types", + "serde", + "serde_json", + "thiserror", + "tracing", +] + [[package]] name = "google-cloud-metadata" version = "0.5.0" @@ -2951,6 +3220,16 @@ dependencies = [ "tokio", ] +[[package]] +name = "google-cloud-metadata" +version = "0.5.0" +source = "git+https://github.com/yoshidan/google-cloud-rust.git?tag=v20240627#8f387a13309707c493d2e581961ee5b0f20631fc" +dependencies = [ + "reqwest 0.12.7", + "thiserror", + "tokio", +] + [[package]] name = "google-cloud-storage" version = "0.20.0" @@ -2963,9 +3242,9 @@ dependencies = [ "base64 0.21.7", "bytes", "futures-util", - "google-cloud-auth", - "google-cloud-metadata", - "google-cloud-token", + "google-cloud-auth 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)", + "google-cloud-metadata 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "google-cloud-token 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "hex", "once_cell", "percent-encoding", @@ -2993,6 +3272,14 @@ dependencies = [ "async-trait", ] +[[package]] +name = "google-cloud-token" +version = "0.1.2" +source = "git+https://github.com/yoshidan/google-cloud-rust.git?tag=v20240627#8f387a13309707c493d2e581961ee5b0f20631fc" +dependencies = [ + "async-trait", +] + [[package]] name = "governor" version = "0.4.2" @@ -3411,6 +3698,18 @@ dependencies = [ "tower-service", ] +[[package]] +name = "hyper-timeout" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1" +dependencies = [ + "hyper 0.14.30", + "pin-project-lite", + "tokio", + "tokio-io-timeout", +] + [[package]] name = "hyper-timeout" version = "0.5.1" @@ -4814,6 +5113,31 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" +[[package]] +name = "open-fastrlp" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "786393f80485445794f6043fd3138854dd109cc6c4bd1a6383db304c9ce9b9ce" +dependencies = [ + "arrayvec 0.7.6", + "auto_impl", + "bytes", + "ethereum-types", + "open-fastrlp-derive", +] + +[[package]] +name = "open-fastrlp-derive" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "003b2be5c6c53c1cfeb0a238b8a1c3915cd410feb684457a36c10038f764bb1c" +dependencies = [ + "bytes", + "proc-macro2 1.0.86", + "quote 1.0.37", + "syn 1.0.109", +] + [[package]] name = "openssl" version = "0.10.66" @@ -4914,7 +5238,7 @@ dependencies = [ "reqwest 0.12.7", "thiserror", "tokio", - "tonic", + "tonic 0.12.3", ] [[package]] @@ -4926,7 +5250,7 @@ dependencies = [ "opentelemetry", "opentelemetry_sdk", "prost 0.13.3", - "tonic", + "tonic 0.12.3", ] [[package]] @@ -5061,6 +5385,15 @@ version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" +[[package]] +name = "pbkdf2" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917" +dependencies = [ + "digest 0.10.7", +] + [[package]] name = "pbkdf2" version = "0.12.2" @@ -5068,6 +5401,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2" dependencies = [ "digest 0.10.7", + "hmac 0.12.1", ] [[package]] @@ -5471,6 +5805,22 @@ dependencies = [ "syn 2.0.77", ] +[[package]] +name = "proptest" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4c2511913b88df1637da85cc8d96ec8e43a3f8bb8ccb71ee1ac240d6f3df58d" +dependencies = [ + "bitflags 2.6.0", + "lazy_static", + "num-traits", + "rand 0.8.5", + "rand_chacha", + "rand_xorshift", + "regex-syntax 0.8.4", + "unarray", +] + [[package]] name = "prost" version = "0.12.6" @@ -5734,6 +6084,15 @@ dependencies = [ "getrandom", ] +[[package]] +name = "rand_xorshift" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d25bf25ec5ae4a3f1b92f929810509a2f53d7dca2f50b794ff57e3face536c8f" +dependencies = [ + "rand_core 0.6.4", +] + [[package]] name = "rand_xoshiro" version = "0.6.0" @@ -6018,6 +6377,15 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "ripemd" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd124222d17ad93a644ed9d011a40f4fb64aa54275c08cc216524a9ea82fb09f" +dependencies = [ + "digest 0.10.7", +] + [[package]] name = "rkyv" version = "0.7.45" @@ -6033,7 +6401,7 @@ dependencies = [ "rkyv_derive", "seahash", "tinyvec", - "uuid", + "uuid 1.10.0", ] [[package]] @@ -6054,9 +6422,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bb919243f34364b6bd2fc10ef797edbfa75f33c252e7998527479c6d6b47e1ec" dependencies = [ "bytes", + "rlp-derive", "rustc-hex", ] +[[package]] +name = "rlp-derive" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e33d7b2abe0c340d8797fe2907d3f20d3b5ea5908683618bfe80df7f621f672a" +dependencies = [ + "proc-macro2 1.0.86", + "quote 1.0.37", + "syn 1.0.109", +] + [[package]] name = "rocksdb" version = "0.21.0" @@ -6313,6 +6693,15 @@ version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" +[[package]] +name = "salsa20" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97a22f5af31f73a954c10289c93e8a50cc23d971e80ee446f1f6f7137a088213" +dependencies = [ + "cipher", +] + [[package]] name = "same-file" version = "1.0.6" @@ -6482,6 +6871,18 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" +[[package]] +name = "scrypt" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f9e24d2b632954ded8ab2ef9fea0a0c769ea56ea98bddbafbad22caeeadf45d" +dependencies = [ + "hmac 0.12.1", + "pbkdf2 0.11.0", + "salsa20", + "sha2 0.10.8", +] + [[package]] name = "sct" version = "0.7.1" @@ -6712,7 +7113,7 @@ dependencies = [ "thiserror", "time", "url", - "uuid", + "uuid 1.10.0", ] [[package]] @@ -7115,7 +7516,7 @@ dependencies = [ "num-bigint 0.4.6", "num-rational", "num-traits", - "pbkdf2", + "pbkdf2 0.12.2", "pin-project", "poly1305", "rand 0.8.5", @@ -7735,7 +8136,7 @@ dependencies = [ "hex", "hmac 0.12.1", "parity-scale-codec", - "pbkdf2", + "pbkdf2 0.12.2", "regex", "schnorrkel", "secrecy", @@ -8128,6 +8529,16 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "tokio-io-timeout" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30b74022ada614a1b4834de765f9bb43877f910cc8ce4be40e89042c9223a8bf" +dependencies = [ + "pin-project-lite", + "tokio", +] + [[package]] name = "tokio-macros" version = "2.4.0" @@ -8149,6 +8560,17 @@ dependencies = [ "tokio", ] +[[package]] +name = "tokio-retry" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f57eb36ecbe0fc510036adff84824dd3c24bb781e21bfa67b69d556aa85214f" +dependencies = [ + "pin-project", + "rand 0.8.5", + "tokio", +] + [[package]] name = "tokio-rustls" version = "0.24.1" @@ -8252,6 +8674,38 @@ dependencies = [ "winnow 0.6.20", ] +[[package]] +name = "tonic" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76c4eb7a4e9ef9d4763600161f12f5070b92a578e1b634db88a6887844c91a13" +dependencies = [ + "async-stream", + "async-trait", + "axum 0.6.20", + "base64 0.21.7", + "bytes", + "flate2", + "h2 0.3.26", + "http 0.2.12", + "http-body 0.4.6", + "hyper 0.14.30", + "hyper-timeout 0.4.1", + "percent-encoding", + "pin-project", + "prost 0.12.6", + "rustls-pemfile 2.1.3", + "rustls-pki-types", + "tokio", + "tokio-rustls 0.25.0", + "tokio-stream", + "tower 0.4.13", + "tower-layer", + "tower-service", + "tracing", + "webpki-roots", +] + [[package]] name = "tonic" version = "0.12.3" @@ -8260,7 +8714,7 @@ checksum = "877c5b330756d856ffcc4553ab34a5684481ade925ecc54bcd1bf02b1d0d4d52" dependencies = [ "async-stream", "async-trait", - "axum", + "axum 0.7.6", "base64 0.22.1", "bytes", "h2 0.4.6", @@ -8268,7 +8722,7 @@ dependencies = [ "http-body 1.0.1", "http-body-util", "hyper 1.4.1", - "hyper-timeout", + "hyper-timeout 0.5.1", "hyper-util", "percent-encoding", "pin-project", @@ -8520,6 +8974,12 @@ dependencies = [ "libc", ] +[[package]] +name = "unarray" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94" + [[package]] name = "unicase" version = "2.7.0" @@ -8655,6 +9115,16 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" +[[package]] +name = "uuid" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" +dependencies = [ + "getrandom", + "serde", +] + [[package]] name = "uuid" version = "1.10.0" @@ -9899,7 +10369,7 @@ name = "zksync_contract_verification_server" version = "0.1.0" dependencies = [ "anyhow", - "axum", + "axum 0.7.6", "serde", "serde_json", "tokio", @@ -10191,8 +10661,14 @@ name = "zksync_eth_signer" version = "0.1.0" dependencies = [ "async-trait", + "ethers-signers", + "google-cloud-gax", + "google-cloud-kms", + "hex", "rlp", "thiserror", + "tokio", + "tracing", "zksync_basic_types", "zksync_crypto_primitives", ] @@ -10301,7 +10777,7 @@ version = "0.1.0" dependencies = [ "anyhow", "async-trait", - "axum", + "axum 0.7.6", "bincode", "thiserror", "tokio", @@ -10464,7 +10940,7 @@ dependencies = [ "anyhow", "assert_matches", "async-trait", - "axum", + "axum 0.7.6", "futures 0.3.30", "itertools 0.10.5", "once_cell", @@ -10544,7 +11020,7 @@ dependencies = [ "anyhow", "assert_matches", "async-trait", - "axum", + "axum 0.7.6", "chrono", "const-decoder", "futures 0.3.30", @@ -10844,7 +11320,7 @@ dependencies = [ "async-trait", "bincode", "flate2", - "google-cloud-auth", + "google-cloud-auth 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)", "google-cloud-storage", "http 1.1.0", "prost 0.12.6", @@ -10878,7 +11354,7 @@ name = "zksync_proof_data_handler" version = "0.1.0" dependencies = [ "anyhow", - "axum", + "axum 0.7.6", "chrono", "hyper 1.4.1", "serde_json", diff --git a/core/bin/zksync_server/src/node_builder.rs b/core/bin/zksync_server/src/node_builder.rs index 234e22894..bdd514863 100644 --- a/core/bin/zksync_server/src/node_builder.rs +++ b/core/bin/zksync_server/src/node_builder.rs @@ -5,6 +5,7 @@ use anyhow::Context; use zksync_config::{ configs::{ da_client::DAClientConfig, secrets::DataAvailabilitySecrets, wallets::Wallets, + eth_sender::SigningMode, GeneralConfig, Secrets, }, ContractsConfig, GenesisConfig, @@ -44,7 +45,7 @@ use zksync_node_framework::{ main_node_strategy::MainNodeInitStrategyLayer, NodeStorageInitializerLayer, }, object_store::ObjectStoreLayer, - pk_signing_eth_client::PKSigningEthClientLayer, + pk_signing_eth_client::{PKSigningEthClientLayer, SigningEthClientType}, pools_layer::PoolsLayerBuilder, postgres_metrics::PostgresMetricsLayer, prometheus_exporter::PrometheusExporterLayer, @@ -73,7 +74,6 @@ use zksync_types::{ pubdata_da::PubdataSendingMode, settlement::SettlementMode, SHARED_BRIDGE_ETHER_TOKEN_ADDRESS, }; use zksync_vlog::prometheus::PrometheusExporterConfig; - /// Macro that looks into a path to fetch an optional config, /// and clones it into a variable. macro_rules! try_load_config { @@ -144,11 +144,29 @@ impl MainNodeBuilder { fn add_pk_signing_client_layer(mut self) -> anyhow::Result { let eth_config = try_load_config!(self.configs.eth); let wallets = try_load_config!(self.wallets.eth_sender); + + let eth_sender = self + .configs + .eth + .clone() + .context("eth_config")? + .sender + .context("sender")?; + + let signing_mode = eth_sender.signing_mode.clone(); + tracing::info!("Using signing mode: {:?}", signing_mode); + + let client_type = match signing_mode { + SigningMode::GcloudKms => SigningEthClientType::GKMSSigningEthClient, + SigningMode::PrivateKey => SigningEthClientType::PKSigningEthClient, + }; + self.node.add_layer(PKSigningEthClientLayer::new( eth_config, self.contracts_config.clone(), self.genesis_config.settlement_layer_id(), wallets, + client_type, )); Ok(self) } diff --git a/core/lib/config/src/configs/eth_sender.rs b/core/lib/config/src/configs/eth_sender.rs index 7b67f0152..3ec14d2f3 100644 --- a/core/lib/config/src/configs/eth_sender.rs +++ b/core/lib/config/src/configs/eth_sender.rs @@ -43,6 +43,7 @@ impl EthConfig { tx_aggregation_paused: false, tx_aggregation_only_prove_and_execute: false, time_in_mempool_in_l1_blocks_cap: 1800, + signing_mode: SigningMode::PrivateKey, }), gas_adjuster: Some(GasAdjusterConfig { default_priority_fee_per_gas: 1000000000, @@ -80,6 +81,13 @@ pub enum ProofLoadingMode { FriProofFromGcs, } +#[derive(Debug, Deserialize, Clone, Copy, PartialEq, Default)] +pub enum SigningMode { + #[default] + PrivateKey, + GcloudKms, +} + #[derive(Debug, Deserialize, Clone, PartialEq)] pub struct SenderConfig { pub aggregated_proof_sizes: Vec, @@ -123,6 +131,8 @@ pub struct SenderConfig { /// Cap of time in mempool for price calculations #[serde(default = "SenderConfig::default_time_in_mempool_in_l1_blocks_cap")] pub time_in_mempool_in_l1_blocks_cap: u32, + /// Type of signing client for Ethereum transactions. + pub signing_mode: SigningMode, } impl SenderConfig { diff --git a/core/lib/config/src/testonly.rs b/core/lib/config/src/testonly.rs index 9b1ec13e2..dbcd0bab2 100644 --- a/core/lib/config/src/testonly.rs +++ b/core/lib/config/src/testonly.rs @@ -17,7 +17,7 @@ use zksync_crypto_primitives::K256PrivateKey; use crate::{ configs::{ - self, da_client::DAClientConfig::Avail, external_price_api_client::ForcedPriceClientConfig, + self, da_client::DAClientConfig::Avail, external_price_api_client::ForcedPriceClientConfig, eth_sender::SigningMode, }, AvailConfig, }; @@ -411,6 +411,7 @@ impl Distribution for EncodeDist { tx_aggregation_paused: false, tx_aggregation_only_prove_and_execute: false, time_in_mempool_in_l1_blocks_cap: self.sample(rng), + signing_mode: SigningMode::PrivateKey, } } } diff --git a/core/lib/env_config/src/eth_sender.rs b/core/lib/env_config/src/eth_sender.rs index 0fd61fd17..08127490c 100644 --- a/core/lib/env_config/src/eth_sender.rs +++ b/core/lib/env_config/src/eth_sender.rs @@ -42,7 +42,7 @@ impl FromEnv for GasAdjusterConfig { #[cfg(test)] mod tests { use zksync_basic_types::pubdata_da::PubdataSendingMode; - use zksync_config::configs::eth_sender::ProofSendingMode; + use zksync_config::configs::eth_sender::{ProofSendingMode, SigningMode}; use super::*; use crate::test_utils::{hash, EnvMutex}; @@ -59,7 +59,6 @@ mod tests { aggregated_block_execute_deadline: 4_000, max_aggregated_tx_gas: 4_000_000, max_eth_tx_data_size: 120_000, - timestamp_criteria_max_allowed_lag: 30, max_aggregated_blocks_to_commit: 3, max_aggregated_blocks_to_execute: 4, @@ -74,6 +73,7 @@ mod tests { tx_aggregation_only_prove_and_execute: false, tx_aggregation_paused: false, time_in_mempool_in_l1_blocks_cap: 2000, + signing_mode: SigningMode::PrivateKey, }), gas_adjuster: Some(GasAdjusterConfig { default_priority_fee_per_gas: 20000000000, @@ -139,6 +139,7 @@ mod tests { ETH_SENDER_SENDER_PUBDATA_SENDING_MODE="Calldata" ETH_WATCH_CONFIRMATIONS_FOR_ETH_EVENT="0" ETH_WATCH_ETH_NODE_POLL_INTERVAL="300" + ETH_SENDER_SENDER_SIGNING_MODE="PrivateKey" ETH_CLIENT_WEB3_URL="http://127.0.0.1:8545" "#; diff --git a/core/lib/eth_client/src/clients/http/mod.rs b/core/lib/eth_client/src/clients/http/mod.rs index 111507c65..830b2a9ec 100644 --- a/core/lib/eth_client/src/clients/http/mod.rs +++ b/core/lib/eth_client/src/clients/http/mod.rs @@ -4,7 +4,7 @@ use vise::{ Buckets, Counter, EncodeLabelSet, EncodeLabelValue, Family, Histogram, LabeledFamily, Metrics, }; -pub use self::signing::{PKSigningClient, SigningClient}; +pub use self::signing::{GKMSSigningClient, PKSigningClient, SigningClient}; mod decl; mod query; diff --git a/core/lib/eth_client/src/clients/http/signing.rs b/core/lib/eth_client/src/clients/http/signing.rs index e602f98a3..e827a411a 100644 --- a/core/lib/eth_client/src/clients/http/signing.rs +++ b/core/lib/eth_client/src/clients/http/signing.rs @@ -2,7 +2,9 @@ use std::{fmt, sync::Arc}; use async_trait::async_trait; use zksync_contracts::hyperchain_contract; -use zksync_eth_signer::{EthereumSigner, PrivateKeySigner, TransactionParameters}; +use zksync_eth_signer::{ + g_kms_signer::GKMSSigner, EthereumSigner, PrivateKeySigner, TransactionParameters, +}; use zksync_types::{ ethabi, web3, Address, K256PrivateKey, SLChainId, EIP_4844_TX_TYPE, H160, U256, }; @@ -40,6 +42,37 @@ impl PKSigningClient { } } +pub type GKMSSigningClient = SigningClient; + +impl GKMSSigningClient { + pub async fn new_raw( + diamond_proxy_addr: Address, + default_priority_fee_per_gas: u64, + chain_id: SLChainId, + query_client: Box>, + key_name: String, + ) -> Self { + let signer = match GKMSSigner::new(key_name, chain_id.0).await { + Ok(s) => s, + Err(e) => panic!("Failed to create GKMSSigner: {:?}", e), + }; + + SigningClient::new( + query_client, + hyperchain_contract(), + signer.get_address().await.unwrap(), + signer, + diamond_proxy_addr, + default_priority_fee_per_gas.into(), + chain_id, + ) + } + + pub fn get_address(&self) -> Address { + self.inner.sender_account + } +} + /// Gas limit value to be used in transaction if for some reason /// gas limit was not set for it. /// diff --git a/core/lib/eth_client/src/clients/mod.rs b/core/lib/eth_client/src/clients/mod.rs index b08f92115..42398fd78 100644 --- a/core/lib/eth_client/src/clients/mod.rs +++ b/core/lib/eth_client/src/clients/mod.rs @@ -6,6 +6,6 @@ mod mock; pub use zksync_web3_decl::client::{Client, DynClient, L1}; pub use self::{ - http::{PKSigningClient, SigningClient}, + http::{GKMSSigningClient, PKSigningClient, SigningClient}, mock::{MockSettlementLayer, MockSettlementLayerBuilder}, }; diff --git a/core/lib/eth_signer/Cargo.toml b/core/lib/eth_signer/Cargo.toml index 92bb47824..0d1da52fa 100644 --- a/core/lib/eth_signer/Cargo.toml +++ b/core/lib/eth_signer/Cargo.toml @@ -17,3 +17,11 @@ zksync_crypto_primitives.workspace = true async-trait.workspace = true rlp.workspace = true thiserror.workspace = true +google-cloud-kms = { git="https://github.com/yoshidan/google-cloud-rust.git", tag="v20240627", features=["eth"]} +google-cloud-gax = { git="https://github.com/yoshidan/google-cloud-rust.git", tag="v20240627"} +hex = "0.4.3" +tracing = "0.1" +ethers-signers = "2.0" + +[dev-dependencies] +tokio = { workspace = true, features = ["full"] } diff --git a/core/lib/eth_signer/src/g_kms_signer.rs b/core/lib/eth_signer/src/g_kms_signer.rs new file mode 100644 index 000000000..bfd5dd0bb --- /dev/null +++ b/core/lib/eth_signer/src/g_kms_signer.rs @@ -0,0 +1,161 @@ +use std::result::Result; + +use ethers_signers::Signer as EthSigner; +use google_cloud_gax::retry::RetrySetting; +use google_cloud_kms::{ + client::{Client, ClientConfig}, + signer::ethereum::Signer, +}; +use hex; +use tracing::{self}; +use zksync_basic_types::{Address, H256, U256,web3::{keccak256, Signature}}; +use zksync_crypto_primitives::{ + EIP712TypedStructure, Eip712Domain, PackedEthSignature, +}; + +use crate::{ + raw_ethereum_tx::{Transaction, TransactionParameters}, + EthereumSigner, SignerError, +}; + +pub const GOOGLE_KMS_OP_KEY_NAME: &str = "GOOGLE_KMS_OP_KEY_NAME"; +pub const GOOGLE_KMS_OP_BLOB_KEY_NAME: &str = "GOOGLE_KMS_OP_BLOB_KEY_NAME"; + +#[derive(Clone)] +pub struct GKMSSigner { + signer: Signer, +} + +impl GKMSSigner { + pub async fn new(key_name: String, _chain_id: u64) -> Result { + let config = ClientConfig::default() + .with_auth() + .await + .map_err(|e| SignerError::SigningFailed(e.to_string()))?; + + let client = Client::new(config) + .await + .map_err(|e| SignerError::SigningFailed(e.to_string()))?; + + let signer = Signer::new(client, &key_name, _chain_id, Some(RetrySetting::default())) + .await + .map_err(|e| SignerError::SigningFailed(e.to_string()))?; + + tracing::info!("KMS signer address: {:?}", hex::encode(signer.address())); + + Ok(GKMSSigner { signer }) + } + + fn u256_to_h256(u: U256) -> H256 { + let mut bytes = [0u8; 32]; + u.to_big_endian(&mut bytes); + H256::from(bytes) + } +} + +#[async_trait::async_trait] +impl EthereumSigner for GKMSSigner { + /// Get Ethereum address that matches the private key. + async fn get_address(&self) -> Result { + Ok(self.signer.address()) + } + + /// Signs typed struct using Ethereum private key by EIP-712 signature standard. + /// Result of this function is the equivalent of RPC calling `eth_signTypedData`. + async fn sign_typed_data( + &self, + domain: &Eip712Domain, + typed_struct: &S, + ) -> Result { + let digest = + H256::from(PackedEthSignature::typed_data_to_signed_bytes(domain, typed_struct).0); + + let signature = self + .signer + .sign_digest(digest.as_bytes()) + .await + .map_err(|e| SignerError::SigningFailed(e.to_string()))?; + + // Convert the signature components to the appropriate format. + let r_h256 = GKMSSigner::u256_to_h256(signature.r); + let s_h256 = GKMSSigner::u256_to_h256(signature.s); + + // Ensure the `v` component is in the correct byte format. + let v_byte = match signature.v.try_into() { + Ok(v) => v, + Err(_) => { + return Err(SignerError::SigningFailed( + "V value conversion failed".to_string(), + )) + } + }; + + // Construct the Ethereum signature from the R, S, and V components. + let eth_sig = PackedEthSignature::from_rsv(&r_h256, &s_h256, v_byte); + + Ok(eth_sig) + } + + /// Signs and returns the RLP-encoded transaction. + async fn sign_transaction( + &self, + raw_tx: TransactionParameters, + ) -> Result, SignerError> { + // According to the code in web3 + // We should use `max_fee_per_gas` as `gas_price` if we use EIP1559 + let gas_price = raw_tx.max_fee_per_gas; + let max_priority_fee_per_gas = raw_tx.max_priority_fee_per_gas; + + let tx = Transaction { + to: raw_tx.to, + nonce: raw_tx.nonce, + gas: raw_tx.gas, + gas_price, + value: raw_tx.value, + data: raw_tx.data, + transaction_type: raw_tx.transaction_type, + access_list: raw_tx.access_list.unwrap_or_default(), + max_priority_fee_per_gas, + max_fee_per_blob_gas: raw_tx.max_fee_per_blob_gas, + blob_versioned_hashes: raw_tx.blob_versioned_hashes, + }; + + let encoded = tx.encode_pub(raw_tx.chain_id, None); + let digest = H256(keccak256(encoded.as_ref())); + + let signature = self + .signer + .sign_digest(digest.as_bytes()) + .await + .map_err(|e| SignerError::SigningFailed(e.to_string()))?; + + let adjusted_v = if let Some(transaction_type) = tx.transaction_type.map(|t| t.as_u64()) { + match transaction_type { + 0 => signature.v + raw_tx.chain_id * 2 + 35, // EIP-155 + _ => signature.v, // EIP-2930 and others + } + } else { + signature.v + raw_tx.chain_id * 2 + 35 // EIP-155 + }; + + let r_h256 = GKMSSigner::u256_to_h256(signature.r); + let s_h256 = GKMSSigner::u256_to_h256(signature.s); + + tracing::debug!( + "KMS sign_transaction signature: v: {}, r: {}, s: {}", + adjusted_v, + hex::encode(r_h256), + hex::encode(s_h256), + ); + + let web3_sig = Signature { + v: adjusted_v, + r: r_h256, + s: s_h256, + }; + + let signed = tx.encode_pub(raw_tx.chain_id, Some(&web3_sig)); + + return Ok(signed); + } +} diff --git a/core/lib/eth_signer/src/lib.rs b/core/lib/eth_signer/src/lib.rs index 8b6025eb1..936a32671 100644 --- a/core/lib/eth_signer/src/lib.rs +++ b/core/lib/eth_signer/src/lib.rs @@ -4,6 +4,7 @@ use zksync_crypto_primitives::{EIP712TypedStructure, Eip712Domain, PackedEthSign pub use crate::{pk_signer::PrivateKeySigner, raw_ethereum_tx::TransactionParameters}; +pub mod g_kms_signer; mod pk_signer; mod raw_ethereum_tx; diff --git a/core/lib/eth_signer/src/raw_ethereum_tx.rs b/core/lib/eth_signer/src/raw_ethereum_tx.rs index bea64305b..3de44f91d 100644 --- a/core/lib/eth_signer/src/raw_ethereum_tx.rs +++ b/core/lib/eth_signer/src/raw_ethereum_tx.rs @@ -268,4 +268,8 @@ impl Transaction { transaction_hash, } } + + pub fn encode_pub(&self, chain_id: u64, signature: Option<&Signature>) -> Vec { + self.encode(chain_id, signature) + } } diff --git a/core/lib/protobuf_config/src/eth.rs b/core/lib/protobuf_config/src/eth.rs index d4ea1d9f2..63a6b61c6 100644 --- a/core/lib/protobuf_config/src/eth.rs +++ b/core/lib/protobuf_config/src/eth.rs @@ -45,6 +45,24 @@ impl proto::PubdataSendingMode { } } +impl proto::SigningMode { + fn new(x: &configs::eth_sender::SigningMode) -> Self { + use configs::eth_sender::SigningMode as From; + match x { + From::PrivateKey => Self::PrivateKey, + From::GcloudKms => Self::GcloudKms, + } + } + + fn parse(&self) -> configs::eth_sender::SigningMode { + use configs::eth_sender::SigningMode as To; + match self { + Self::PrivateKey => To::PrivateKey, + Self::GcloudKms => To::GcloudKms, + } + } +} + impl ProtoRepr for proto::Eth { type Type = configs::eth_sender::EthConfig; @@ -117,6 +135,10 @@ impl ProtoRepr for proto::Sender { time_in_mempool_in_l1_blocks_cap: self .time_in_mempool_in_l1_blocks_cap .unwrap_or(Self::Type::default_time_in_mempool_in_l1_blocks_cap()), + signing_mode: required(&self.signing_mode) + .and_then(|x| Ok(proto::SigningMode::try_from(*x)?)) + .context("signing_mode")? + .parse(), }) } @@ -150,6 +172,7 @@ impl ProtoRepr for proto::Sender { tx_aggregation_only_prove_and_execute: Some(this.tx_aggregation_only_prove_and_execute), tx_aggregation_paused: Some(this.tx_aggregation_paused), time_in_mempool_in_l1_blocks_cap: Some(this.time_in_mempool_in_l1_blocks_cap), + signing_mode: Some(proto::SigningMode::new(&this.signing_mode).into()), } } } diff --git a/core/lib/protobuf_config/src/proto/config/eth_sender.proto b/core/lib/protobuf_config/src/proto/config/eth_sender.proto index 6438573e0..ce4549067 100644 --- a/core/lib/protobuf_config/src/proto/config/eth_sender.proto +++ b/core/lib/protobuf_config/src/proto/config/eth_sender.proto @@ -6,7 +6,8 @@ message ETH { optional Sender sender = 1; // required optional GasAdjuster gas_adjuster = 2; // required optional ETHWatch watcher = 3; // required - reserved 4; reserved "web3_url"; + reserved 4; + reserved "web3_url"; } enum ProofSendingMode { @@ -27,6 +28,11 @@ enum PubdataSendingMode { RELAYED_L2_CALLDATA = 3; } +enum SigningMode { + PRIVATE_KEY = 0; + GCLOUD_KMS = 1; +} + message Sender { repeated uint64 aggregated_proof_sizes = 1; // ? optional uint64 wait_confirmations = 2; // optional @@ -45,10 +51,12 @@ message Sender { optional uint64 l1_batch_min_age_before_execute_seconds = 15; // optional; s optional uint64 max_acceptable_priority_fee_in_gwei = 16; // required; gwei optional PubdataSendingMode pubdata_sending_mode = 18; // required - reserved 19; reserved "proof_loading_mode"; + reserved 19; + reserved "proof_loading_mode"; optional bool tx_aggregation_paused = 20; // required optional bool tx_aggregation_only_prove_and_execute = 21; // required optional uint32 time_in_mempool_in_l1_blocks_cap = 22; // optional + optional SigningMode signing_mode = 99; // required } message GasAdjuster { diff --git a/core/node/node_framework/src/implementations/layers/pk_signing_eth_client.rs b/core/node/node_framework/src/implementations/layers/pk_signing_eth_client.rs index fdef23a40..4f072cb97 100644 --- a/core/node/node_framework/src/implementations/layers/pk_signing_eth_client.rs +++ b/core/node/node_framework/src/implementations/layers/pk_signing_eth_client.rs @@ -3,7 +3,7 @@ use zksync_config::{ configs::{wallets, ContractsConfig}, EthConfig, }; -use zksync_eth_client::clients::PKSigningClient; +use zksync_eth_client::clients::{GKMSSigningClient, PKSigningClient}; use zksync_types::SLChainId; use crate::{ @@ -15,12 +15,20 @@ use crate::{ }; /// Wiring layer for [`PKSigningClient`]. +#[derive(Debug)] +#[non_exhaustive] +pub enum SigningEthClientType { + PKSigningEthClient, + GKMSSigningEthClient, +} + #[derive(Debug)] pub struct PKSigningEthClientLayer { eth_sender_config: EthConfig, contracts_config: ContractsConfig, sl_chain_id: SLChainId, wallets: wallets::EthSender, + client_type: SigningEthClientType, } #[derive(Debug, FromContext)] @@ -43,12 +51,14 @@ impl PKSigningEthClientLayer { contracts_config: ContractsConfig, sl_chain_id: SLChainId, wallets: wallets::EthSender, + client_type: SigningEthClientType, ) -> Self { Self { eth_sender_config, contracts_config, sl_chain_id, wallets, + client_type, } } } @@ -63,34 +73,88 @@ impl WiringLayer for PKSigningEthClientLayer { } async fn wire(self, input: Self::Input) -> Result { - let private_key = self.wallets.operator.private_key(); - let gas_adjuster_config = self - .eth_sender_config - .gas_adjuster - .as_ref() - .context("gas_adjuster config is missing")?; - let EthInterfaceResource(query_client) = input.eth_client; - - let signing_client = PKSigningClient::new_raw( - private_key.clone(), - self.contracts_config.diamond_proxy_addr, - gas_adjuster_config.default_priority_fee_per_gas, - self.sl_chain_id, - query_client.clone(), - ); - let signing_client = BoundEthInterfaceResource(Box::new(signing_client)); - - let signing_client_for_blobs = self.wallets.blob_operator.map(|blob_operator| { - let private_key = blob_operator.private_key(); - let signing_client_for_blobs = PKSigningClient::new_raw( - private_key.clone(), - self.contracts_config.diamond_proxy_addr, - gas_adjuster_config.default_priority_fee_per_gas, - self.sl_chain_id, - query_client, - ); - BoundEthInterfaceForBlobsResource(Box::new(signing_client_for_blobs)) - }); + let signing_client; + let mut signing_client_for_blobs = None; + + match self.client_type { + SigningEthClientType::PKSigningEthClient => { + let private_key = self.wallets.operator.private_key(); + let gas_adjuster_config = self + .eth_sender_config + .gas_adjuster + .as_ref() + .context("gas_adjuster config is missing")?; + let EthInterfaceResource(query_client) = input.eth_client; + + let sc = PKSigningClient::new_raw( + private_key.clone(), + self.contracts_config.diamond_proxy_addr, + gas_adjuster_config.default_priority_fee_per_gas, + self.sl_chain_id, + query_client.clone(), + ); + signing_client = BoundEthInterfaceResource(Box::new(sc)); + + signing_client_for_blobs = self.wallets.blob_operator.map(|blob_operator| { + let private_key = blob_operator.private_key(); + let signing_client_for_blobs = PKSigningClient::new_raw( + private_key.clone(), + self.contracts_config.diamond_proxy_addr, + gas_adjuster_config.default_priority_fee_per_gas, + self.sl_chain_id, + query_client, + ); + BoundEthInterfaceForBlobsResource(Box::new(signing_client_for_blobs)) + }); + } + SigningEthClientType::GKMSSigningEthClient => { + let gas_adjuster_config = self + .eth_sender_config + .gas_adjuster + .as_ref() + .context("gas_adjuster config is missing")?; + + let gkms_op_key_name = std::env::var("GOOGLE_KMS_OP_KEY_NAME").ok(); + tracing::info!( + "KMS op key name: {:?}", + std::env::var("GOOGLE_KMS_OP_KEY_NAME") + ); + + let EthInterfaceResource(query_client) = input.eth_client; + + let sc = GKMSSigningClient::new_raw( + self.contracts_config.diamond_proxy_addr, + gas_adjuster_config.default_priority_fee_per_gas, + self.sl_chain_id, + query_client.clone(), + gkms_op_key_name + .expect("gkms_op_key_name is required but was None") + .to_string(), + ) + .await; + + signing_client = BoundEthInterfaceResource(Box::new(sc)); + + let gkms_op_blob_key_name = std::env::var("GOOGLE_KMS_OP_BLOB_KEY_NAME").ok(); + tracing::info!( + "KMS op blob key name: {:?}", + std::env::var("GOOGLE_KMS_OP_BLOB_KEY_NAME") + ); + + if let Some(key_name) = gkms_op_blob_key_name { + let blobs_resources = GKMSSigningClient::new_raw( + self.contracts_config.diamond_proxy_addr, + gas_adjuster_config.default_priority_fee_per_gas, + self.sl_chain_id, + query_client, + key_name.to_string(), + ) + .await; + signing_client_for_blobs = + Some(BoundEthInterfaceForBlobsResource(Box::new(blobs_resources))); + }; + } + }; Ok(Output { signing_client, diff --git a/etc/env/base/eth_sender.toml b/etc/env/base/eth_sender.toml index ad5709551..97c5a6c1b 100644 --- a/etc/env/base/eth_sender.toml +++ b/etc/env/base/eth_sender.toml @@ -48,6 +48,8 @@ max_acceptable_priority_fee_in_gwei = 100000000000 pubdata_sending_mode = "Blobs" +signing_mode = "PrivateKey" + [eth_sender.gas_adjuster] # Priority fee to be used by GasAdjuster (in wei). default_priority_fee_per_gas = 1_000_000_000