-
Notifications
You must be signed in to change notification settings - Fork 20
Subsidize adding an Ethereum compatible control key #2403
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
Merged
Merged
Changes from all commits
Commits
Show all changes
15 commits
Select commit
Hold shift + click to select a range
4d4caf2
Add ability to set the expiration block for adding a key for free
shannonwells 337edb1
benchmarks, spec_version
shannonwells 35e9691
update readme, linting
shannonwells 0a9947d
PR clean up: rustdocs, remove unused imports & code.
shannonwells 1589995
more cleanup
shannonwells edccb98
please the linter
shannonwells bf6b5e3
updates after rebase
shannonwells a0c3686
* use new trait fn is_ethereum_address to help determine free txn eli…
shannonwells 74b2a17
* Remove README changes
shannonwells 3a7f5d0
change some wording, undo changes that are no longer needed
shannonwells a10f9e7
linting, plus upgrade eslint due to crashing/maybe bug
shannonwells 8f6d7f3
remove unnecessary benchmark feature config
shannonwells 68139e9
reduce capacity fee instead of weight
shannonwells 502283c
don't need this check any more b/c we don't have a free extrinsic case
shannonwells 0ff2ee2
update to use new ethereum utils library in e2e test. respond to PR …
shannonwells File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
import { KeyringPair } from '@polkadot/keyring/types'; | ||
import { AddKeyData, Extrinsic, ExtrinsicHelper } from '../scaffolding/extrinsicHelpers'; | ||
import { | ||
assertEvent, | ||
CENTS, | ||
createKeys, | ||
createMsa, | ||
createMsaAndProvider, | ||
DOLLARS, | ||
generateAddKeyPayload, | ||
getEthereumKeyPairFromUnifiedAddress, | ||
signPayloadSr25519, | ||
stakeToProvider, | ||
} from '../scaffolding/helpers'; | ||
import { getUnifiedAddress, getUnifiedPublicKey } from '../scaffolding/ethereum'; | ||
import assert from 'assert'; | ||
import { getFundingSource } from '../scaffolding/funding'; | ||
import { u64 } from '@polkadot/types'; | ||
import { MessageSourceId } from '@frequency-chain/api-augment/interfaces'; | ||
import { createAddKeyData, signEip712 } from '@frequency-chain/ethereum-utils'; | ||
import { u8aToHex } from '@polkadot/util'; | ||
|
||
const fundingSource = getFundingSource(import.meta.url); | ||
|
||
describe('adding an Ethereum key for low cost', function () { | ||
let providerKeys; | ||
let providerMsaId; | ||
|
||
before(async function () { | ||
providerKeys = await createKeys('KeyAdder'); | ||
providerMsaId = await createMsaAndProvider(fundingSource, providerKeys, 'KeyAdder', 10n * CENTS); | ||
await stakeToProvider(fundingSource, fundingSource, providerMsaId, 6n * DOLLARS); | ||
}); | ||
|
||
// create a delegator MSA account with new keys, | ||
// create a new Ethereum keypair, | ||
// call generateAddKeyCallParamsUsingKeys, | ||
// return the new keys, the resulting payload, and both signatures. | ||
async function generateAddKeyCallParams() { | ||
const ethereumKeyringPair = await createKeys('Ethereum', 'ethereum'); | ||
const [delegatorMsaId, delegatorKeys] = await createMsa(fundingSource, 10n * CENTS); | ||
const { addKeyPayload, delegatorSig, newSig } = await generateAddKeyCallParamsUsingKeys( | ||
delegatorKeys, | ||
delegatorMsaId, | ||
ethereumKeyringPair | ||
); | ||
return { delegatorKeys, addKeyPayload, delegatorSig, newSig }; | ||
} | ||
|
||
// create AddKeyData using the provided keys. | ||
// use the keys to sign the AddKeyData in an AddKey payload. | ||
// return the new keys, the payload, and both signatures. | ||
async function generateAddKeyCallParamsUsingKeys( | ||
delegatorKeys: KeyringPair, | ||
delegatorMsaId: u64, | ||
ethereumKeyringPair: KeyringPair | ||
) { | ||
const addKeyPayload = await generateAddKeyPayload({}); | ||
addKeyPayload.msaId = delegatorMsaId; | ||
addKeyPayload.newPublicKey = getUnifiedPublicKey(ethereumKeyringPair); | ||
|
||
const srSignatureaddKeyData = ExtrinsicHelper.api.registry.createType('PalletMsaAddKeyData', addKeyPayload); | ||
const delegatorSrSignature = signPayloadSr25519(delegatorKeys, srSignatureaddKeyData); | ||
|
||
const ethereumSecretKey = u8aToHex( | ||
getEthereumKeyPairFromUnifiedAddress(getUnifiedAddress(ethereumKeyringPair)).secretKey | ||
); | ||
const eip712AddKeyData = createAddKeyData( | ||
addKeyPayload.msaId.toBigInt(), | ||
u8aToHex(addKeyPayload.newPublicKey), | ||
addKeyPayload.expiration | ||
); | ||
const ecdsaSignature = await signEip712(ethereumSecretKey, eip712AddKeyData); | ||
|
||
return { addKeyPayload, delegatorSig: delegatorSrSignature, newSig: ecdsaSignature }; | ||
} | ||
|
||
it('addPublicKeyToMsa costs less for capacity call with eligibility conditions', async function () { | ||
// SET UP | ||
const { delegatorKeys, addKeyPayload, delegatorSig, newSig } = await generateAddKeyCallParams(); | ||
|
||
// the extrinsic will be called by a provider with stake. | ||
const addPublicKeyOp = new Extrinsic( | ||
() => | ||
ExtrinsicHelper.api.tx.msa.addPublicKeyToMsa( | ||
getUnifiedPublicKey(delegatorKeys), | ||
delegatorSig, | ||
newSig, | ||
addKeyPayload | ||
), | ||
providerKeys, | ||
ExtrinsicHelper.api.events.msa.PublicKeyAdded | ||
); | ||
|
||
// ACT pay with capacity using the provider. | ||
const { eventMap } = await addPublicKeyOp.payWithCapacity(); | ||
|
||
// ASSERT it's a very small fee, but not free. | ||
assertEvent(eventMap, 'msa.PublicKeyAdded'); | ||
const capacityFee = ExtrinsicHelper.getCapacityFee(eventMap); | ||
assert(capacityFee > 0); | ||
assert(capacityFee < 1_320_000n); // ~1.3 CENTS | ||
|
||
// add another key; this should cost a lot more | ||
const thirdKeyEth = await createKeys('Eth2', 'ethereum'); | ||
const delegatorMsaId: MessageSourceId = addKeyPayload.msaId || new u64(ExtrinsicHelper.api.registry, 0); | ||
const newParams = await generateAddKeyCallParamsUsingKeys(delegatorKeys, delegatorMsaId, thirdKeyEth); | ||
|
||
// again to be submitted by provider. | ||
const addThirdKeyOp = new Extrinsic( | ||
() => | ||
ExtrinsicHelper.api.tx.msa.addPublicKeyToMsa( | ||
getUnifiedPublicKey(delegatorKeys), | ||
newParams.delegatorSig, | ||
newParams.newSig, | ||
newParams.addKeyPayload | ||
), | ||
providerKeys, | ||
ExtrinsicHelper.api.events.msa.PublicKeyAdded | ||
); | ||
|
||
// ACT pay with capacity to add a third key | ||
const { eventMap: eventMap2 } = await addThirdKeyOp.payWithCapacity(); | ||
assertEvent(eventMap2, 'msa.PublicKeyAdded'); | ||
const thirdKeyCapacityFee = ExtrinsicHelper.getCapacityFee(eventMap2); | ||
// 4260363n vs | ||
// 1278109n | ||
assert(thirdKeyCapacityFee > capacityFee); | ||
assert(thirdKeyCapacityFee < 5n * CENTS); | ||
}); | ||
}); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.