-
Notifications
You must be signed in to change notification settings - Fork 31
Fetch deposit BTC address (contract code) #25
Conversation
Shouldn't this PR be linked against #14? |
This is functioning and ready for review. It just is blocked by #24 being merged, with the artifacts included |
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 just a partial implementation of what we need to close #14.
Currently, this PR contains the code to retrieve a public key (from tbtc demo script: https://github.com/keep-network/tbtc/blob/master/implementation/demo/2_fetch_public_key.js).
But we also need to add conversion of the key to the BTC address. More details in #25 (comment).
client/src/Deposit.js
Outdated
// 1. Call deposit to create new keep | ||
// 2. Watch for ECDSAKeepCreated event from ECDSAKeepFactory contract | ||
// 3. call get public key | ||
export async function initializeDeposit(depositAddress) { |
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.
Will we need this function? I think we can remove it.
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.
Yep 💯 I think I removed it in #24
client/src/Deposit.js
Outdated
} | ||
|
||
export async function waitDepositBTCPublicKey(depositAddress) { |
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.
How do we use this function? I can see that in getDepositBTCPublicKey
you're finding RegisteredPubkey
event.
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.
We should also monitor when the keep is ready with the public key so we can transition from initialize deposit page to retrieve the public key.
I think that for simplification we can just wait for a couple of seconds now (or transition manually on button click) - single signer keep calculates and publishes the key almost immediately.
Later we will need to emit an event from the keep contract and monitor it in the dapp.
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.
Yeah exactly!
So the reason this function is here is to do that. However, due to the current Ganache testchain setup I've got, there's a race between keep-ecdsa emitting the signature and me starting to listen for the event (due to the fact that you can only listen once you have the deposit address).
So to mitigate this, we will have to do some polling instead.
client/src/Deposit.js
Outdated
|
||
console.log(`Call getPublicKey for deposit [${deposit.address}]`) | ||
|
||
let result |
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.
We could simplify
let result
try {
result = await deposit.retrieveSignerPubkey()
} catch(err) {
console.error(`retrieveSignerPubkey failed: ${err}`)
}
to
const result = await deposit.retrieveSignerPubkey()
.catch((err)=> {
console.error(`retrieveSignerPubkey failed: ${err}`)
})
client/src/Deposit.js
Outdated
const publicKeyX = eventList[0].args._signingGroupPubkeyX | ||
const publicKeyY = eventList[0].args._signingGroupPubkeyY | ||
|
||
console.log(`Registered public key:\nX: ${publicKeyX}\nY: ${publicKeyY}`) | ||
|
||
return [publicKeyX, publicKeyY] | ||
const address = publicKeyToP2WPKHaddress( | ||
`${publicKeyX.slice(2)}${publicKeyY.slice(2)}`, |
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.
What is the result of ${publicKeyX.slice(2)}${publicKeyY.slice(2)}
? Why do we do slice(2)
?
We should concatenate X
and Y
coordinates to 64 bytes. Note that if a coordinate's length is lesser than 32-bytes we should pad it with zeros.
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.
Yeah it's to remove the 0x
prefix from the strings :)
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.
Maybe prefer a regex in case you aren't getting the string you expect in the future? Also it's self-documenting :)
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.
Haha I think this miiight be a bit of overkill. Considering it's an event emitted from EVM, the value is uint256, so the string should always be the full length and in the 0x format - these assumptions are validated in the test.
Still tried the regex though ;)
('0x'+'0'.repeat(40)).match(/^(?:0x)([a-fA-F0-9]{40})$/)`
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.
We need to add a comment on what's happening and why we slice the values.
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.
On second thought, it's not overkill, I couldn't find any docs from Web3 on events.
How's this for self-documenting code!
let publicKeyX = eventList[0].args._signingGroupPubkeyX
let publicKeyY = eventList[0].args._signingGroupPubkeyY
publicKeyX = publicKeyX.replace('0x', '')
publicKeyY = publicKeyY.replace('0x', '')
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.
Nice move!
@nkuba also ready for review |
client/test/DepositTest.js
Outdated
@@ -1,6 +1,7 @@ | |||
const Web3 = require('web3') | |||
|
|||
import { createDeposit, setDefaults } from '../src' | |||
import { createDeposit, setDefaults, initializeDeposit, getDepositBTCPublicKey, waitDepositBTCPublicKey } from '../src' | |||
import { setElectrumConfig } from '../src/FundingProof'; |
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.
We don't need this import, right?
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.
But I do need that linter! Hahaha
client/test/DepositTest.js
Outdated
@@ -1,6 +1,7 @@ | |||
const Web3 = require('web3') | |||
|
|||
import { createDeposit, setDefaults } from '../src' | |||
import { createDeposit, setDefaults, initializeDeposit, getDepositBTCPublicKey, waitDepositBTCPublicKey } from '../src' |
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.
Do we need all the functions imported here? It looks to me that we need to add only getDepositBTCPublicKey
to the previous imports.
client/src/Deposit.js
Outdated
@@ -34,4 +40,68 @@ export async function createDeposit() { | |||
const depositAddress = logs[0].args.depositCloneAddress | |||
|
|||
return depositAddress | |||
} | |||
|
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 duplicated empty line.
client/src/Deposit.js
Outdated
import { | ||
publicKeyToP2WPKHaddress, | ||
Network | ||
} from '../../lib/tbtc-helpers/src/Address' |
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 be } from 'tbtc-helpers/src/Address'
? We have tbtc-helpers
as a package dependency.
client/src/Deposit.js
Outdated
} | ||
|
||
|
||
// A complement to getDepositBTCPublicKey. |
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.
Update to JS docs style we use in other functions.
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.
So if we're not using it maybe we shouldn't commit it? Will we use it for the demo dapp?
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.
@nkuba I'd prefer not to throw away the code if it's going to be useful in immediate future. 😄
In this case (and I know I keep saying this), we are building a library out of the client/
package. As I explained in the comment, the purpose of this function, while not needed yet, will be needed in the production environment.
I would write a test for the function too, so that it's not just dangling there in the code...?
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.
A good practice is to write a code for immediate future but mainnet is not that immediate. Experience shows that such a code is usually dangling, after a month or two, nobody knows why it's there, it gets out of date quickly and it is maintained only to have the compilation passing with no effort in understanding what it really does.
If we were to use this code in a week or two, this would be fine to leave it, but if it's a matter of months, I'd propose to ☠️ it.
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.
Ok in which case I'll remove it.
client/src/Deposit.js
Outdated
* @param {string} depositAddress the address of a Deposit contract | ||
* @returns a bech32-encoded Bitcoin address | ||
*/ | ||
export async function getDepositBTCPublicKey(depositAddress) { |
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 name getDepositBTCPublicKey
is not accurate. We're getting the BTC address from this function.
We already have a function for this purpose in:
async function getAddress(depositAddress) { |
Can we move the implementation to the function I linked?
Actually getBTCadress
name would be better than getAddress
.
It's up to you if we keep it in Deposit.js
or FundingTransaction.js
file.
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.
Yep 100% agree - will do.
client/src/Deposit.js
Outdated
export async function getDepositBTCPublicKey(depositAddress) { | ||
const tbtcSystem = await TBTCSystem.deployed() | ||
|
||
// 1. Request it from the deposit |
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.
Let's be more specific and replace it
/this
in comments with public key
and others.
client/src/Deposit.js
Outdated
}) | ||
|
||
// 2. Parse the logs to get it | ||
// we can't get this from result.logs, since it's emitted in another contract |
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.
What's more, we should do it as we do here (with fromBlock: '0'
) because retrieveSignerPubkey
might fail because the key was already retrieved (see my previous comment). Let's have it in a comment.
client/src/Deposit.js
Outdated
|
||
console.log(`Registered public key for deposit ${depositAddress}:\nX: ${publicKeyX}\nY: ${publicKeyY}`) | ||
|
||
const address = publicKeyToP2WPKHaddress( |
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.
address
-> btcAddress
Let's edit this PR and set base branch to |
We will upload the artifacts deployed on our internal testnet in #35. Let's don't commit them in this PR. |
Ready @nkuba |
Let's merge master to this branch and see if CI passes. |
client/src/FundingTransaction.js
Outdated
// TODO: Implement: | ||
// 1. Get keep public key from the deposit | ||
// 2. Calculate P2WPKH address from the key | ||
|
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.
So many blank lines, let's remove them in one of the upcoming PRs.
client/src/FundingTransaction.js
Outdated
} | ||
|
||
|
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.
Same here about blank lines.
package.json
Outdated
@@ -16,6 +16,7 @@ | |||
"redux": "^4.0.4", | |||
"redux-saga": "^1.0.5", | |||
"tbtc-client": "file:client", | |||
"tbtc-helpers": "file:lib/tbtc-helpers", |
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.
Do we need this dependency in dapp's package.json
? We should be using only tbtc-client
.
@@ -1,12 +1,61 @@ | |||
const Address = require('tbtc-helpers').Address |
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.
CI is failing because of this removal.
d2d1845
to
030b620
Compare
|
Yeah @pdyraga see this thread |
Refs #14