-
Notifications
You must be signed in to change notification settings - Fork 13
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
feat: spark contract #377
base: main
Are you sure you want to change the base?
feat: spark contract #377
Conversation
LexLuthr
commented
Jan 21, 2025
•
edited
Loading
edited
- Contract
- Test - contract
- Auto update process
- Delete command
- Test in mainnet
- README
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 reviewed the design and have concerns about the feasibility/usability of the proposed solution. PTAL at my comments below.
### **Fetch Peer Data** | ||
|
||
```javascript | ||
const peerData = await contract.getPeerData(1000); | ||
console.log(peerData.peerID); | ||
console.log(peerData.signedMessage); | ||
``` | ||
|
||
### Verify the signature for auth check | ||
|
||
```javascript | ||
import { HttpJsonRpcConnector, LotusClient } from "filecoin.js"; | ||
import * as libp2pCrypto from "@libp2p/crypto"; // Ensure this library is installed | ||
import * as multihashes from "multihashes"; // For decoding PeerID | ||
|
||
/** | ||
* Fetch miner's PeerID and verify the signature of a message. | ||
* @param {string} minerAddress - Filecoin miner address | ||
* @param {Buffer} message - The message that was signed | ||
* @param {Buffer} signature - The signature to verify | ||
*/ | ||
async function verifyMinerSignature(minerAddress, message, signature) { | ||
try { | ||
// Set up the Filecoin RPC client | ||
const rpcUrl = "http://127.0.0.1:1234/rpc/v0"; // Replace with your Filecoin Lotus RPC URL | ||
const connector = new HttpJsonRpcConnector({ url: rpcUrl }); | ||
const lotusClient = new LotusClient(connector); | ||
|
||
// Step 1: Fetch miner info | ||
const minerInfo = await lotusClient.state.minerInfo(minerAddress); | ||
|
||
if (!minerInfo || !minerInfo.PeerId) { | ||
throw new Error("Could not retrieve PeerID from miner info."); | ||
} | ||
|
||
// Extract PeerID | ||
const { PeerId } = minerInfo; | ||
console.log("Retrieved PeerID:", PeerId); | ||
|
||
// Step 2: Decode PeerID to obtain the public key | ||
const decodedPeerID = multihashes.decode(Buffer.from(PeerId, "base64")); | ||
const publicKeyBytes = decodedPeerID.digest; | ||
|
||
// Step 3: Generate a Libp2p public key object | ||
const publicKey = await libp2pCrypto.keys.unmarshalPublicKey(publicKeyBytes); | ||
|
||
// Step 4: Verify the signature | ||
const isValid = await publicKey.verify(message, signature); | ||
|
||
if (isValid) { | ||
console.log("Signature is valid."); | ||
return true; | ||
} else { | ||
console.log("Signature is invalid."); | ||
return false; | ||
} | ||
} catch (error) { | ||
console.error("Error during verification:", error.message); | ||
throw error; | ||
} | ||
} | ||
``` |
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.
Thank you for including a detailed JavaScript example showing how to use this new smart contract.
IIUC, the messages (transactions) modifying the MinerID->PeerID mapping are signed using the libp2p PeerID as found in MinerInfo state, is that correct?
Does the smart contract verify those signatures and reject messages where the signature does not match, or is it necessary to always validate the signatures on the client trying to map miner to IPNI PeerID?
If client-side validation is required, how do you envision handling the situation when the miner changes their libp2p PeerID stored in the MinerInfo state?
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, they signed with existing on chain ID.
We don't verify the signature in contract. It is too expensive to do so. We only verify that sender is a control address for the miner address.
Hmm! For Curio it would be an easy fix. We can verify the signature and if it does not match then update the entry. This would ensure that if peerID changes then same is updated in the contract as well. Although, in real world, users won't be changing peerID. In fact, we don't have any options to update it in a cluster.
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.
Fixed the peerID signature mismatch in Curio code. It checks and pushes a fix if required.
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.
Perfect! Can you please document this requirement somewhere in the docs so that other implementers like Venus know about 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.
This is not a library function. Not sure what you want me to document. This is implementation specific. Venus might want to do something else.
37d479e
to
e174761
Compare
e174761
to
f4aa99b
Compare
fec0bf3
to
652fbac
Compare
652fbac
to
0ddc513
Compare
|
||
/** | ||
* Fetch miner's PeerID and verify the signature of a message. | ||
* @param {string} minerAddress - Filecoin miner 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.
See, this line expects the minerAddress to be an f0
string.
IIUC, to fully validate the mapping, we need also need to check that minerAddress
matches message.miner
and minerInfo.PeerID
matches message.peerID
.
It would be great to include this step in the example code too. Maybe as a new function showing how to fully verify the mapping entry?
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.
README will be updated once I have the tested the contract. README was written for the first version.
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.
In #377 (comment), we were discussing the case where the message is signed using the PeerID found in the MinerInfo state.
In #377 (comment), we are discussing that the message should be signed by the PeerID found in the mapping.
As far as I understand, these two Peer IDs will be different in Curio, and that's the reason for introducing this smart contract. (Otherwise, we could keep using the PeerID in the MinerInfo state.) It's my understanding that message.peerID
is the important one, and therefore the message should be signed using message.peerID
.
I understand the example showing PeerID verification is outdated now. I am just flagging this as something to consider while updating the README for the new version.
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.
Matching minerID is unnecessary here. We are already matching that in the contract. It is the function input.
I can show certain things in example but no way write the exact code folks might need.
You last comment is very confusing. Please write out in detail what exactly are you expecting here.
FYI:
- We sign message using the on chain peerID.
- Signing it with IPNI specific peerID is useless. This would not be secure enough. IPNI ads are already signed by this peerID for verification.
So, I am not sure why you think signing with IPNI specific peerID would be better.
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.
Thank you for simplifying the contract!
I have a few comments to consider, see above.
The new version looks good to me 👍🏻 Can you please let me know what is the address of the mainnet deployment we can use in Spark and the FRC?