Skip to content

Commit d1b5774

Browse files
authored
Merge pull request #19 from lordshashank/label-integration
Integrates Multi chain config to prover
2 parents bb8216e + 76ecfb2 commit d1b5774

File tree

9 files changed

+496
-133
lines changed

9 files changed

+496
-133
lines changed

contract-tools/xchain/xchain.go

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -661,7 +661,19 @@ func (a *aggregator) sendDeal(ctx context.Context, aggCommp cid.Cid, transferID
661661
return fmt.Errorf("failed to translate onramp address (%s) into a "+
662662
"Filecoin f4 address: %w", a.onrampAddr.Hex(), err)
663663
}
664-
664+
chainID, err := a.client.ChainID(ctx)
665+
if err != nil {
666+
return fmt.Errorf("failed to get chain ID: %w", err)
667+
}
668+
// Encode the chainID as uint256
669+
encodedChainID, err := encodeChainID(chainID)
670+
if err != nil {
671+
return fmt.Errorf("failed to encode chainID: %w", err)
672+
}
673+
dealLabel, err := market.NewLabelFromBytes(encodedChainID)
674+
if err != nil {
675+
return fmt.Errorf("failed to create deal label: %w", err)
676+
}
665677
proposal := market.ClientDealProposal{
666678
Proposal: market.DealProposal{
667679
PieceCID: aggCommp,
@@ -673,7 +685,7 @@ func (a *aggregator) sendDeal(ctx context.Context, aggCommp cid.Cid, transferID
673685
EndEpoch: dealEnd,
674686
StoragePricePerEpoch: fbig.NewInt(0),
675687
ProviderCollateral: providerCollateral,
676-
//Label: , // TOOD we might need to set this, we'll see
688+
Label: dealLabel,
677689
},
678690
// Signature is unchecked since client is smart contract
679691
ClientSignature: crypto.Signature{
@@ -986,6 +998,7 @@ func loadPrivateKey(cfg *Config) (*bind.TransactOpts, error) {
986998
if err := ks.Unlock(a, os.Getenv("XCHAIN_PASSPHRASE")); err != nil {
987999
return nil, fmt.Errorf("failed to unlock keystore: %w", err)
9881000
}
1001+
9891002
return bind.NewKeyStoreTransactorWithChainID(ks, a, big.NewInt(int64(cfg.ChainID)))
9901003
}
9911004

@@ -1005,3 +1018,24 @@ func LoadAbi(path string) (*abi.ABI, error) {
10051018
}
10061019
return &parsedABI, nil
10071020
}
1021+
1022+
func encodeChainID(chainID *big.Int) ([]byte, error) {
1023+
// Define the ABI arguments
1024+
uint256Type, err := abi.NewType("uint256", "", nil)
1025+
if err != nil {
1026+
return nil, fmt.Errorf("failed to create uint256 type: %w", err)
1027+
}
1028+
1029+
arguments := abi.Arguments{
1030+
{Type: uint256Type}, // chainID is a uint256 in Solidity
1031+
}
1032+
1033+
// Pack the chainID into a byte array
1034+
data, err := arguments.Pack(chainID)
1035+
if err != nil {
1036+
return nil, fmt.Errorf("failed to encode chainID: %w", err)
1037+
}
1038+
1039+
return data, nil
1040+
}
1041+
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
package main
2+
3+
import (
4+
"context"
5+
"encoding/hex"
6+
"fmt"
7+
"math/big"
8+
"testing"
9+
10+
"github.com/ethereum/go-ethereum/accounts/abi"
11+
"github.com/ethereum/go-ethereum/ethclient"
12+
"github.com/stretchr/testify/assert"
13+
)
14+
15+
// Test function to test chainID encoding
16+
func TestChainIdEncoding(t *testing.T) {
17+
configPath := "~/.xchain/config.json" // Replace with the actual path to your config file
18+
19+
config, err := LoadConfig(configPath);
20+
if err != nil {
21+
t.Fatalf("failed to unmarshal config: %v", err)
22+
}
23+
24+
// Connect to the Ethereum client
25+
client, err := ethclient.Dial(config.Api)
26+
if err != nil {
27+
t.Fatalf("failed to connect to the Ethereum client: %v", err)
28+
}
29+
30+
// Query the chain ID
31+
chainID, err := client.ChainID(context.Background())
32+
if err != nil {
33+
t.Fatalf("failed to get chain ID: %v", err)
34+
}
35+
36+
// Encode the chainID
37+
encodedChainID, err := encodeChainID(chainID)
38+
if err != nil {
39+
t.Fatalf("failed to encode chainID: %v", err)
40+
}
41+
42+
fmt.Println("Encoded chainID: ", encodedChainID)
43+
fmt.Println("chainID: ", chainID)
44+
hexEncodedChainID := hex.EncodeToString(encodedChainID)
45+
fmt.Printf("Encoded ChainID in Hex: %s\n", hexEncodedChainID)
46+
decodedChainID, err := decodeChainID(encodedChainID)
47+
if err != nil {
48+
t.Fatalf("failed to decode chainID: %v", err)
49+
}
50+
fmt.Println("Decoded chainID: ", decodedChainID)
51+
assert.Equal(t, decodedChainID, chainID, "Encoded chainID does not match expected value")
52+
}
53+
54+
func decodeChainID(data []byte) (*big.Int, error) {
55+
// Define the ABI arguments
56+
uint256Type, err := abi.NewType("uint256", "", nil)
57+
if err != nil {
58+
return nil, fmt.Errorf("failed to create uint256 type: %w", err)
59+
}
60+
61+
arguments := abi.Arguments{
62+
{Type: uint256Type}, // chainID is a uint256 in Solidity
63+
}
64+
65+
// Unpack the byte array into a slice of interface{}
66+
unpacked, err := arguments.Unpack(data)
67+
if err != nil {
68+
return nil, fmt.Errorf("failed to decode chainID: %w", err)
69+
}
70+
71+
// Extract the chainID from the unpacked slice
72+
if len(unpacked) == 0 {
73+
return nil, fmt.Errorf("no data unpacked")
74+
}
75+
76+
chainID, ok := unpacked[0].(*big.Int)
77+
if !ok {
78+
return nil, fmt.Errorf("failed to assert type to *big.Int")
79+
}
80+
81+
return chainID, nil
82+
}

src/Cid.sol

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,25 +8,40 @@ import "./Const.sol";
88

99
library Cid {
1010
// cidToPieceCommitment converts a CID to a piece commitment.
11-
function cidToPieceCommitment(bytes memory _cb) internal pure returns (bytes32) {
11+
function cidToPieceCommitment(
12+
bytes memory _cb
13+
) internal pure returns (bytes32) {
1214
require(
1315
_cb.length == CID_COMMP_HEADER_LENGTH + MERKLE_TREE_NODE_SIZE,
1416
"wrong length of CID"
1517
);
1618
require(
17-
keccak256(abi.encodePacked(_cb[0], _cb[1], _cb[2], _cb[3], _cb[4], _cb[5], _cb[6])) ==
18-
keccak256(abi.encodePacked(CID_COMMP_HEADER)),
19+
keccak256(
20+
abi.encodePacked(
21+
_cb[0],
22+
_cb[1],
23+
_cb[2],
24+
_cb[3],
25+
_cb[4],
26+
_cb[5],
27+
_cb[6]
28+
)
29+
) == keccak256(abi.encodePacked(CID_COMMP_HEADER)),
1930
"wrong content of CID header"
2031
);
2132
bytes32 res;
2233
assembly {
23-
res := mload(add(add(_cb, CID_COMMP_HEADER_LENGTH), MERKLE_TREE_NODE_SIZE))
34+
res := mload(
35+
add(add(_cb, CID_COMMP_HEADER_LENGTH), MERKLE_TREE_NODE_SIZE)
36+
)
2437
}
2538
return res;
2639
}
2740

2841
// pieceCommitmentToCid converts a piece commitment to a CID.
29-
function pieceCommitmentToCid(bytes32 _commp) internal pure returns (bytes memory) {
42+
function pieceCommitmentToCid(
43+
bytes32 _commp
44+
) internal pure returns (bytes memory) {
3045
bytes memory cb = abi.encodePacked(CID_COMMP_HEADER, _commp);
3146
return cb;
3247
}

src/Const.sol

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,8 @@ uint8 constant MERKLE_TREE_NODE_SIZE = 32;
1414
bytes32 constant TRUNCATOR = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3f;
1515
uint64 constant BYTES_IN_INT = 8;
1616
uint64 constant CHECKSUM_SIZE = 16;
17-
uint64 constant ENTRY_SIZE = uint64(MERKLE_TREE_NODE_SIZE) + 2 * BYTES_IN_INT + CHECKSUM_SIZE;
17+
uint64 constant ENTRY_SIZE = uint64(MERKLE_TREE_NODE_SIZE) +
18+
2 *
19+
BYTES_IN_INT +
20+
CHECKSUM_SIZE;
1821
uint64 constant BYTES_IN_DATA_SEGMENT_ENTRY = 2 * MERKLE_TREE_NODE_SIZE;

src/OnRamp.sol

Lines changed: 60 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,12 @@ import {Cid} from "./Cid.sol";
66
import {TRUNCATOR} from "./Const.sol";
77
import {DataAttestation} from "./Oracles.sol";
88

9-
109
// Adapted from https://github.com/lighthouse-web3/raas-starter-kit/blob/main/contracts/data-segment/Proof.sol
1110
// adapted rather than imported to
1211
// 1) avoid build issues
13-
// 2) avoid npm deps
12+
// 2) avoid npm deps
1413
//3) avoid use of deprecated @zondax/filecoin-solidity
1514
contract PODSIVerifier {
16-
1715
// ProofData is a Merkle proof
1816
struct ProofData {
1917
uint64 index;
@@ -30,9 +28,18 @@ contract PODSIVerifier {
3028
}
3129

3230
// computeRoot computes the root of a Merkle tree given a leaf and a Merkle proof.
33-
function computeRoot(ProofData memory d, bytes32 subtree) internal pure returns (bytes32) {
34-
require(d.path.length < 64, "merkleproofs with depths greater than 63 are not supported");
35-
require(d.index >> d.path.length == 0, "index greater than width of the tree");
31+
function computeRoot(
32+
ProofData memory d,
33+
bytes32 subtree
34+
) internal pure returns (bytes32) {
35+
require(
36+
d.path.length < 64,
37+
"merkleproofs with depths greater than 63 are not supported"
38+
);
39+
require(
40+
d.index >> d.path.length == 0,
41+
"index greater than width of the tree"
42+
);
3643

3744
bytes32 carry = subtree;
3845
uint64 index = d.index;
@@ -51,7 +58,10 @@ contract PODSIVerifier {
5158
}
5259

5360
// computeNode computes the parent node of two child nodes
54-
function computeNode(bytes32 left, bytes32 right) internal pure returns (bytes32) {
61+
function computeNode(
62+
bytes32 left,
63+
bytes32 right
64+
) internal pure returns (bytes32) {
5565
bytes32 digest = sha256(abi.encodePacked(left, right));
5666
return truncate(digest);
5767
}
@@ -63,17 +73,16 @@ contract PODSIVerifier {
6373
}
6474
}
6575

66-
6776
contract OnRampContract is PODSIVerifier {
68-
struct Offer {
77+
struct Offer {
6978
bytes commP;
7079
uint64 size;
7180
string location;
7281
uint256 amount;
7382
IERC20 token;
7483
}
7584
// Possible rearrangement:
76-
// struct Hint {string location, uint64 size} ?
85+
// struct Hint {string location, uint64 size} ?
7786
// struct Payment {uint256 amount, IERC20 token}?
7887

7988
event DataReady(Offer offer, uint64 id);
@@ -86,7 +95,6 @@ contract OnRampContract is PODSIVerifier {
8695
mapping(uint64 => bool) public provenAggregations;
8796
mapping(bytes => uint64) public commPToAggregateID;
8897

89-
9098
function setOracle(address oracle_) external {
9199
if (dataProofOracle == address(0)) {
92100
dataProofOracle = oracle_;
@@ -96,7 +104,10 @@ contract OnRampContract is PODSIVerifier {
96104
}
97105

98106
function offerData(Offer calldata offer) external payable returns (uint64) {
99-
require(offer.token.transferFrom(msg.sender, address(this), offer.amount), "Payment transfer failed");
107+
require(
108+
offer.token.transferFrom(msg.sender, address(this), offer.amount),
109+
"Payment transfer failed"
110+
);
100111

101112
uint64 id = nextOfferId++;
102113
offers[id] = offer;
@@ -105,39 +116,66 @@ contract OnRampContract is PODSIVerifier {
105116
return id;
106117
}
107118

108-
function commitAggregate(bytes calldata aggregate, uint64[] calldata claimedIDs, ProofData[] calldata inclusionProofs, address payoutAddr) external {
119+
function commitAggregate(
120+
bytes calldata aggregate,
121+
uint64[] calldata claimedIDs,
122+
ProofData[] calldata inclusionProofs,
123+
address payoutAddr
124+
) external {
109125
uint64[] memory offerIDs = new uint64[](claimedIDs.length);
110126
uint64 aggId = nextAggregateID++;
111-
// Prove all offers are committed by aggregate commP
127+
// Prove all offers are committed by aggregate commP
112128
for (uint64 i = 0; i < claimedIDs.length; i++) {
113129
uint64 offerID = claimedIDs[i];
114130
offerIDs[i] = offerID;
115-
require(verify(inclusionProofs[i], Cid.cidToPieceCommitment(aggregate), Cid.cidToPieceCommitment(offers[offerID].commP)), "Proof verification failed");
131+
require(
132+
verify(
133+
inclusionProofs[i],
134+
Cid.cidToPieceCommitment(aggregate),
135+
Cid.cidToPieceCommitment(offers[offerID].commP)
136+
),
137+
"Proof verification failed"
138+
);
116139
}
117140
aggregations[aggId] = offerIDs;
118141
aggregationPayout[aggId] = payoutAddr;
119142
commPToAggregateID[aggregate] = aggId;
120143
}
121144

122-
function verifyDataStored(uint64 aggID, uint idx, uint64 offerID) external view returns (bool) {
145+
function verifyDataStored(
146+
uint64 aggID,
147+
uint idx,
148+
uint64 offerID
149+
) external view returns (bool) {
123150
require(provenAggregations[aggID], "Provided aggregation not proven");
124-
require(aggregations[aggID][idx] == offerID, "Aggregation does not include offer");
151+
require(
152+
aggregations[aggID][idx] == offerID,
153+
"Aggregation does not include offer"
154+
);
125155

126156
return true;
127157
}
128158

129159
// Called by oracle to prove the data is stored
130-
function proveDataStored( DataAttestation calldata attestation) external {
131-
require(msg.sender == dataProofOracle, "Only oracle can prove data stored");
160+
function proveDataStored(DataAttestation calldata attestation) external {
161+
require(
162+
msg.sender == dataProofOracle,
163+
"Only oracle can prove data stored"
164+
);
132165
uint64 aggID = commPToAggregateID[attestation.commP];
133166
require(aggID != 0, "Aggregate not found");
134167

135168
// transfer payment to the receiver
136169
for (uint i = 0; i < aggregations[aggID].length; i++) {
137170
uint64 offerID = aggregations[aggID][i];
138-
require(offers[offerID].token.transfer(aggregationPayout[aggID], offers[offerID].amount), "Payment transfer failed");
139-
}
171+
require(
172+
offers[offerID].token.transfer(
173+
aggregationPayout[aggID],
174+
offers[offerID].amount
175+
),
176+
"Payment transfer failed"
177+
);
178+
}
140179
provenAggregations[aggID] = true;
141180
}
142181
}
143-

0 commit comments

Comments
 (0)