-
Notifications
You must be signed in to change notification settings - Fork 47
Minimal Bridging Stock Cordapp sample #117
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
Minimal Bridging Stock Cordapp sample #117
Conversation
…fidential identities. Bridge* flows follows the structure of similar Move flows from tokens SDK.
…rst token to bridge instead
…lance in Corda network
…mappings, via Cordapp config file
…ridged instead of a first token within BA
0a08b83 to
a15e293
Compare
| require(instruction.programId == Token2022.PROGRAM_ID) { "Solana program id must be Token2022 program" } | ||
|
|
||
| require(instruction.accounts[1].pubkey == bridgingCommand.targetAddress) { "Target in instructions does not match command" } | ||
|
|
||
| @Suppress("MagicNumber") | ||
| require(instruction.data.size == 9) { "Expecting 9 bytes of instruction data" } | ||
|
|
||
| val instructionBytes = ByteBuffer.wrap(instruction.data.bytes).order(ByteOrder.LITTLE_ENDIAN) | ||
|
|
||
| val tokenInstruction = instructionBytes.get().toInt() | ||
|
|
||
| val amount = instructionBytes.getLong() | ||
| require(tokenInstruction == TokenProgramBase.MINT_TO_INSTRUCTION) { "Token instruction must be MINT_TO_INSTRUCTION" } | ||
|
|
||
| require(amount == lockedSum) { "Locked amount of $lockedSum must match requested mint amount $amount." } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is brittle and hard to read. SolanaInstruction implements equals/hashCode and so you can instead compare the instruction against the expected Token2022.mintTo instruction object.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
|
|
||
| @InitiatingFlow | ||
| @StartableByRPC | ||
| class BridgeToken( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This flow seems to be just for testing? Better suited to be just in the test class, rather than part of the CorDapp/library.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This class was removed voiding the comment.
| } | ||
| val solanaAccountMapping = serviceHub.cordaService(SolanaAccountsMappingService::class.java) | ||
| val destination = | ||
| solanaAccountMapping.participants[singlePreviousOwner.name]!! //TODO handle null |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Throw an exception if previous owner is not configured.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| val solanaAccountMapping = serviceHub.cordaService(SolanaAccountsMappingService::class.java) | ||
| val destination = | ||
| solanaAccountMapping.participants[singlePreviousOwner.name]!! //TODO handle null | ||
| val mint = solanaAccountMapping.mints[cordaTokenId]!! //TODO handle null |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ditto
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| class BridgeFungibleTokenFlow( | ||
| val holder: AbstractParty, | ||
| val observers: List<Party> = emptyList(), | ||
| val token: StateAndRef<FungibleToken>, //TODO should be FungibleToken, TODO change to any TokenType would need amendments to UUID retrieval below |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think these TODOs are no longer needed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done, TODO is gone
| fun bridgeTokens( | ||
| serviceHub: ServiceHub, | ||
| transactionBuilder: TransactionBuilder, | ||
| additionalOutput: List<ContractState>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need to add additional outputs for the user. they can do it themselves after or before calling this method.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was slightly refactored, however the code her needs to be complete self-contained as this Token-SDK class follow Template Method Patter, and we don't have access to TransactionBuilder outside it(before the flow is run).
| /** | ||
| * Adds a set of bridging commands to a transaction using specific outputs. | ||
| */ | ||
| @Suspendable |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this really need to be suspendable?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove unnecessary suspendable annotation in https://github.com/corda/corda-solana-toolkit/pull/8/commits/928c5d6b8929f19d348a7bb2074a27a0647b9951
| val outputGroups: Map<IssuedTokenType, List<AbstractToken>> = | ||
| transactionBuilder.outputStates() | ||
| .map { it.data } | ||
| .filterIsInstance<AbstractToken>() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this not be FungibleToken?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The fix was already applied on other PR
| "Input and output token types must correspond to each other when moving tokensToIssue" | ||
| } | ||
|
|
||
| transactionBuilder.apply { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you remove this apply. it adds an extra indention for just the addCommand call.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
|
|
||
| val quantity = amount.toDecimal() | ||
| .toLong() //TODO this is quantity for Solana, should it be 1 to 1 what is bridged on Corda? | ||
| bridgeToken( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't this utility function itself call addMoveTokens rather than assume it has been called? It makes a better utility function that correctly sets up the tx builder. Otherwise, bridgeToken is assuming the output and input states are already correctly present.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, this utility method no longer exists , logic in a flow call
|
closing, superseded by https://github.com/corda/corda-solana-toolkit/pull/8 |
The simplest bridge flow and sample to bridge a given token with Bridging Authority containing mappings to Solana accounts.
Because Confidential Identity is not used, the bridge is a move to self (owner is still Bridging Authority).
No notary change -single notary for move and brige is used.
The test uses Mock Network and issues 2 tokens and bridge one, first an participant moves token to Bridging Authority, then test calls Bridging Authority to bridge (no vault listener implemented yet), and the test asserts that token balance appears on Solana.
Temporally Bridging SDK code is here as separate modules, will be moved to platform.