Skip to content
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

Open
wants to merge 16 commits into
base: main
Choose a base branch
from
Open

feat: spark contract #377

wants to merge 16 commits into from

Conversation

LexLuthr
Copy link
Contributor

@LexLuthr LexLuthr commented Jan 21, 2025

  • Contract
  • Test - contract
  • Auto update process
  • Delete command
  • Test in mainnet
  • README

Copy link

@bajtos bajtos left a 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.

market/ipni/ipni-provider/spark.go Show resolved Hide resolved
market/ipni/spark/sol/README.md Show resolved Hide resolved
market/ipni/spark/sol/README.md Show resolved Hide resolved
Comment on lines +154 to +215
### **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;
}
}
```
Copy link

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?

Copy link
Contributor Author

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.

Copy link
Contributor Author

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.

Copy link

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?

Copy link
Contributor Author

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.

@LexLuthr LexLuthr force-pushed the feat/spark-contract branch from 37d479e to e174761 Compare January 31, 2025 08:37
@LexLuthr LexLuthr force-pushed the feat/spark-contract branch from e174761 to f4aa99b Compare January 31, 2025 08:42
@LexLuthr LexLuthr force-pushed the feat/spark-contract branch from fec0bf3 to 652fbac Compare January 31, 2025 10:02
@LexLuthr LexLuthr force-pushed the feat/spark-contract branch from 652fbac to 0ddc513 Compare January 31, 2025 10:04

/**
* Fetch miner's PeerID and verify the signature of a message.
* @param {string} minerAddress - Filecoin miner address
Copy link

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?

Copy link
Contributor Author

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.

Copy link

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.

Copy link
Contributor Author

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:

  1. We sign message using the on chain peerID.
  2. 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.

Copy link

@bajtos bajtos left a 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?

@LexLuthr LexLuthr marked this pull request as ready for review February 6, 2025 13:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants