-
Notifications
You must be signed in to change notification settings - Fork 91
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support threshold signing in bridge withdrawer #1937
Closed
Labels
bridge-withdrawer
code touching the bridge-withdrawer service
enhancement
New feature or request
stale
Comments
This was referenced Feb 5, 2025
This issue is stale because it has been open 45 days with no activity. Remove stale label or this issue |
github-merge-queue bot
pushed a commit
that referenced
this issue
Mar 20, 2025
Loading
Loading status checks…
## Summary support FROST ed25519 threshold signing in the bridge withdrawer. ## Background improves security of the withdrawer over having one private key used; instead, we can employ an m-of-n threshold signature scheme to sign withdrawals. ## Changes - create `FrostParticipantService` gRPC proto definition, which is to be implemented by a binary which contains a FROST secret key partial that participates in the threshold signing process - update withdrawer config/setup to support single signer (previous behaviour) or threshold signing via the `Signer` trait - create `FrostSigner` which has gRPC clients for the signing participants - `FrostSigner.sign()` performs the signing process by calling each participant for their commitment (part 1) and signature share (part 2) and finally aggregates the shares to create a valid signature. - `FrostSigner.sign()` will fail if it does not receive responses from at least the minimum number of signers required. the min number of signers is determined during key generation, which is done completely separately. ## Testing blackbox tests with mock signer servers have been added. also, this was tested with a 2/2 threshold signer node setup. withdrawal transactions are successfully signed, submitted, and included on the sequencer. see https://www.notion.so/astria-org/bridge-threshold-withdrawer-testing-1936bd31a90c803ab33ccc1221f545a1?pvs=4 use the following testing keys which are for 2/2 threshold and represent astria address `astria1w2lxx9p02u7u934ljl060wannqm40g3y089lmh` put the following keys into their own files. pubkey package: ```bash { "header": { "version": 0, "ciphersuite": "FROST-ED25519-SHA512-v1" }, "verifying_shares": { "0100000000000000000000000000000000000000000000000000000000000000": "bd209bd0c47806fee2db29bde0b705f6a191602f0307e8d959d74f189ae92e9e", "0200000000000000000000000000000000000000000000000000000000000000": "0a677e1c6ad0c1906bf6ac53810b29efcb9ca9e7ab50fe9fca3ae49e613b922f" }, "verifying_key": "ecbe5e2fbaaf23f14ca43f34d71ad733c57afcadeb5782809af48a3da17b9b69" ``` secret key 1: ```bash { "header": { "version": 0, "ciphersuite": "FROST-ED25519-SHA512-v1" }, "identifier": "0100000000000000000000000000000000000000000000000000000000000000", "signing_share": "4b45de055567d7a2027bfc9a2463de4aaa6f2df995180e638dc938013e9bf70e", "verifying_share": "bd209bd0c47806fee2db29bde0b705f6a191602f0307e8d959d74f189ae92e9e", "verifying_key": "ecbe5e2fbaaf23f14ca43f34d71ad733c57afcadeb5782809af48a3da17b9b69", "min_signers": 2 } ``` secret key 2: ```bash { "header": { "version": 0, "ciphersuite": "FROST-ED25519-SHA512-v1" }, "identifier": "0200000000000000000000000000000000000000000000000000000000000000", "signing_share": "29a52cd248df9a7bb2346fb4ed53318f0bff320985c8e49062c68e4fd0012d0f", "verifying_share": "0a677e1c6ad0c1906bf6ac53810b29efcb9ca9e7ab50fe9fca3ae49e613b922f", "verifying_key": "ecbe5e2fbaaf23f14ca43f34d71ad733c57afcadeb5782809af48a3da17b9b69", "min_signers": 2 } ``` checkout `noot/frost-participant` (see #1960) build astria-cli, astria-bridge-withdrawer, astria-bridge-signer and astria-sequencer. run anvil (using this as fake rollup evm node for testing) run astria-sequencer + cometbft as normal transfer funds from funded address to withdrawer address ```bash ./target/debug/astria-cli sequencer transfer --amount 100000000 \ --private-key 2bd806c97f0e00af1a1fc3328fa763a9269723c8db8fac4f93af71db186d6e90 \ --sequencer-url http://localhost:26657 \ --sequencer.chain-id astria astria1w2lxx9p02u7u934ljl060wannqm40g3y089lmh ``` initialize bridge account on astria, with `astria1w2lxx9p02u7u934ljl060wannqm40g3y089lmh` being the withdrawer address ```bash ./target/debug/astria-cli sequencer init-bridge-account \ --private-key 2bd806c97f0e00af1a1fc3328fa763a9269723c8db8fac4f93af71db186d6e90 \ --withdrawer-address astria1w2lxx9p02u7u934ljl060wannqm40g3y089lmh \ --sequencer-url http://localhost:26657 \ --sequencer.chain-id astria \ --rollup-name test ``` result: ```bash sending tx from address: astria1rsxyjrcm255ds9euthjx6yc3vrjt9sxrm9cfgm InitBridgeAccount completed! Included in block: 1252 Rollup name: test Rollup ID: n4bQgYhMfWWaL-qgxVrQFaO_TxsrC4Is0V1sFbDwCgg= ``` deploy contracts to anvil using `astria-bridge-contracts` - set `.env` and `source .env` ```bash PRIVATE_KEY=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 RPC_URL="http://localhost:8545" BASE_CHAIN_ASSET_PRECISION=9 BASE_CHAIN_BRIDGE_ADDRESS="astria1rsxyjrcm255ds9euthjx6yc3vrjt9sxrm9cfgm" BASE_CHAIN_ASSET_DENOMINATION="nria" ``` - `forge script script/AstriaWithdrawer.s.sol:AstriaWithdrawerScript --rpc-url $RPC_URL --broadcast --sig "deploy()" -vvvv` - contract deployed at `0x5FbDB2315678afecb367f032d93F642f64180aa3` , update `.env` again run two astria-bridge-signers, one with grpc port `9001` and first secret key package, second with grpc port `9002` and second secret key package. start the bridge withdrawer, configured for 2/2 threshold (make sure to update pubkey package path): ```bash ASTRIA_BRIDGE_WITHDRAWER_FROST_THRESHOLD_SIGNING_ENABLED=true ASTRIA_BRIDGE_WITHDRAWER_FROST_MIN_SIGNERS=2 ASTRIA_BRIDGE_WITHDRAWER_FROST_PUBLIC_KEY_PACKAGE_PATH="pub_bridge.key" ASTRIA_BRIDGE_WITHDRAWER_FROST_PARTICIPANT_ENDPOINTS="http://127.0.0.1:9001,http://127.0.0.1:9002" ASTRIA_BRIDGE_WITHDRAWER_SEQUENCER_BRIDGE_ADDRESS="astria1rsxyjrcm255ds9euthjx6yc3vrjt9sxrm9cfgm" ASTRIA_BRIDGE_WITHDRAWER_ETHEREUM_CONTRACT_ADDRESS="0x5FbDB2315678afecb367f032d93F642f64180aa3" ``` finally, send a withdrawal on the rollup: ```bash forge script script/AstriaWithdrawer.s.sol:AstriaWithdrawerScript \ --rpc-url $RPC_URL --broadcast --sig "withdrawToSequencer()" -vvvv ``` in the withdrawer, should see: ```bash 2025-02-10T17:33:57.417370Z INFO process_batch: astria_bridge_withdrawer::bridge_withdrawer::submitter: withdraw batch successfully executed. sequencer.block=41 sequencer.tx_hash=69E3997A2A67CD4716D1051D9962219FBCEF9F3F7557C276D9F4D414D30166F2 rollup.height=4 batch.value=1000 ``` ## Changelogs Changelogs updated. ## Related Issues closes #1937 --------- Co-authored-by: Richard Janis Goldschmidt <[email protected]>
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Labels
bridge-withdrawer
code touching the bridge-withdrawer service
enhancement
New feature or request
stale
PRD (private): https://www.notion.so/astria-org/Rough-Sketch-of-Threshold-Signing-for-Bridge-17e6bd31a90c8056a8c8fb980620ace7
┆Issue Number: ENG-1081
The text was updated successfully, but these errors were encountered: