Skip to content

Commit

Permalink
refactor: claim interface (#189)
Browse files Browse the repository at this point in the history
  • Loading branch information
nugaon authored Sep 25, 2023
1 parent 0ea3cfb commit e9d59c9
Show file tree
Hide file tree
Showing 4 changed files with 153 additions and 137 deletions.
79 changes: 42 additions & 37 deletions src/Redistribution.sol
Original file line number Diff line number Diff line change
Expand Up @@ -82,20 +82,15 @@ contract Redistribution is AccessControl, Pausable {
bytes32[] proofSegments2;
bytes32 proveSegment2;
// proveSegmentIndex2 known from deterministic random selection;
uint64 chunkSpan;

bytes32[] proofSegments3;
// _proveSegment3 known, is equal _proveSegment2
// proveSegmentIndex3 know, is equal _proveSegmentIndex2;
// chunkSpan2 is equal to chunkSpan (as the data is the same)

// address signer; it is provided by the postage stamp contract
bytes signature;
bytes32 chunkAddr;
bytes32 postageId;
uint64 chunkSpan;
uint64 index;
uint64 timeStamp;
SOCProof[] socProofAttached;
//
PostageProof postageProof;
SOCProof[] socProof;
}

struct SOCProof {
Expand All @@ -105,7 +100,15 @@ contract Redistribution is AccessControl, Pausable {
bytes32 chunkAddr; // wrapped chunk address
}

// ----------------------------- State variables ------------------------------
struct PostageProof{
bytes signature;
bytes32 postageId;
uint64 index;
uint64 timeStamp;
// address signer; it is provided by the postage stamp contract
// bytes32 chunkAddr; it equals to the proveSegment argument
}


// The address of the linked PostageStamp contract.
IPostageStamp public PostageContract;
Expand Down Expand Up @@ -233,8 +236,10 @@ contract Redistribution is AccessControl, Pausable {
error BalanceValidationFailed(bytes32); // Stamp alive: batch remaining balance validation failed for attached stamp
error BucketDiffers(bytes32); // Stamp aligned: postage bucket differs from address bucket
error InclusionProofFailed(uint8, bytes32);
// 1 = RC inclusion proof failed for element, 2 = First sister segment in data must match,
// 3 = Inclusion proof failed for original address of element, 4 = Inclusion proof failed for transformed address of element
// 1 = RC inclusion proof failed for element
// 2 = First sister segment in data must match,
// 3 = Inclusion proof failed for original address of element
// 4 = Inclusion proof failed for transformed address of element
error RandomElementCheckFailed(); // Random element order check failed
error LastElementCheckFailed(); // Last element order check failed
error ReserveCheckFailed(); // Reserve size estimation check failed
Expand Down Expand Up @@ -919,65 +924,65 @@ contract Redistribution is AccessControl, Pausable {
// ----------------------------- Claim verifications ------------------------------

function socFunction(ChunkInclusionProof calldata entryProof) internal pure {
if (entryProof.socProofAttached.length == 0) return;
if (entryProof.socProof.length == 0) return;

if (
!Signatures.socVerify(
entryProof.socProofAttached[0].signer, // signer Ethereum address to check against
entryProof.socProofAttached[0].signature,
entryProof.socProofAttached[0].identifier,
entryProof.socProofAttached[0].chunkAddr
entryProof.socProof[0].signer, // signer Ethereum address to check against
entryProof.socProof[0].signature,
entryProof.socProof[0].identifier,
entryProof.socProof[0].chunkAddr
)
) {
revert SocVerificationFailed(entryProof.socProofAttached[0].chunkAddr);
revert SocVerificationFailed(entryProof.socProof[0].chunkAddr);
}

if (
calculateSocAddress(entryProof.socProofAttached[0].identifier, entryProof.socProofAttached[0].signer) !=
calculateSocAddress(entryProof.socProof[0].identifier, entryProof.socProof[0].signer) !=
entryProof.proveSegment
) {
revert SocCalcNotMatching(entryProof.socProofAttached[0].chunkAddr);
revert SocCalcNotMatching(entryProof.socProof[0].chunkAddr);
}
}

function stampFunction(ChunkInclusionProof calldata entryProof) internal view {
// authentic
uint8 batchDepth = PostageContract.batchDepth(entryProof.postageId);
uint8 bucketDepth = PostageContract.batchBucketDepth(entryProof.postageId);
uint32 postageIndex = getPostageIndex(entryProof.index);
uint8 batchDepth = PostageContract.batchDepth(entryProof.postageProof.postageId);
uint8 bucketDepth = PostageContract.batchBucketDepth(entryProof.postageProof.postageId);
uint32 postageIndex = getPostageIndex(entryProof.postageProof.index);
uint256 maxPostageIndex = postageStampIndexCount(batchDepth, bucketDepth);
// available
if (postageIndex >= maxPostageIndex) {
revert IndexOutsideSet(entryProof.chunkAddr);
revert IndexOutsideSet(entryProof.postageProof.postageId);
}

// available
address batchOwner = PostageContract.batchOwner(entryProof.postageId);
address batchOwner = PostageContract.batchOwner(entryProof.postageProof.postageId);

// alive
if (PostageContract.remainingBalance(entryProof.postageId) < PostageContract.minimumInitialBalancePerChunk()) {
revert BalanceValidationFailed(entryProof.chunkAddr);
if (PostageContract.remainingBalance(entryProof.postageProof.postageId) < PostageContract.minimumInitialBalancePerChunk()) {
revert BalanceValidationFailed(entryProof.postageProof.postageId);
}

// aligned
uint64 postageBucket = getPostageBucket(entryProof.index);
uint64 postageBucket = getPostageBucket(entryProof.postageProof.index);
uint64 addressBucket = addressToBucket(entryProof.proveSegment, bucketDepth);
if (postageBucket != addressBucket) {
revert BucketDiffers(entryProof.chunkAddr);
revert BucketDiffers(entryProof.postageProof.postageId);
}

// authorized
if (
!Signatures.postageVerify(
batchOwner,
entryProof.signature,
entryProof.postageProof.signature,
entryProof.proveSegment,
entryProof.postageId,
entryProof.index,
entryProof.timeStamp
entryProof.postageProof.postageId,
entryProof.postageProof.index,
entryProof.postageProof.timeStamp
)
) {
revert SigRecoveryFailed(entryProof.chunkAddr);
revert SigRecoveryFailed(entryProof.postageProof.postageId);
}
}

Expand Down Expand Up @@ -1007,8 +1012,8 @@ contract Redistribution is AccessControl, Pausable {
revert InclusionProofFailed(2, calculatedTransformedAddr);
}

bytes32 originalAddress = entryProof.socProofAttached.length > 0
? entryProof.socProofAttached[0].chunkAddr // soc attestation in socFunction
bytes32 originalAddress = entryProof.socProof.length > 0
? entryProof.socProof[0].chunkAddr // soc attestation in socFunction
: entryProof.proveSegment;

if (
Expand All @@ -1024,7 +1029,7 @@ contract Redistribution is AccessControl, Pausable {
}

// In case of SOC, the transformed address is hashed together with its address in the sample
if (entryProof.socProofAttached.length > 0) {
if (entryProof.socProof.length > 0) {
calculatedTransformedAddr = keccak256(
abi.encode(
entryProof.proveSegment, // SOC address
Expand Down
41 changes: 22 additions & 19 deletions test/Redistribution.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -833,6 +833,7 @@ describe('Redistribution', function () {
deployer,
'0x6cccd65a68bc5f7c19a273e9567ebf4b968a13c9be74fc99ad90159730eff219'
);
// console.log('anchor1', await redistribution.currentSeed());

const { proof1, proof2, proofLast, hash: sanityHash, depth: sanityDepth } = node5_soc_proof1;

Expand All @@ -848,6 +849,7 @@ describe('Redistribution', function () {
await r_node_5.reveal(overlay_5, sanityDepth, sanityHash, reveal_nonce_5);

currentSeed = await redistribution.currentSeed();
// console.log('anchor2', currentSeed);

expect((await r_node_5.currentReveals(0)).hash).to.be.eq(sanityHash);
expect((await r_node_5.currentReveals(0)).overlay).to.be.eq(overlay_5);
Expand All @@ -868,19 +870,19 @@ describe('Redistribution', function () {
it('should claim pot by generated CAC sampling', async function () {
const { sampleHashString, proofParams } = await generatedSampling();

expect(proofParams.proof1.socProofAttached).to.have.length(0);
expect(proofParams.proof2.socProofAttached).to.have.length(0);
expect(proofParams.proofLast.socProofAttached).to.have.length(0);
expect(proofParams.proof1.socProof).to.have.length(0);
expect(proofParams.proof2.socProof).to.have.length(0);
expect(proofParams.proofLast.socProof).to.have.length(0);
const tx2 = await r_node_5.claim(proofParams.proof1, proofParams.proof2, proofParams.proofLast);
await claimEventChecks(tx2, sampleHashString, hexlify(depth));
});

it('should claim pot by generated SOC sampling', async function () {
const { sampleHashString, proofParams } = await generatedSampling(true);

expect(proofParams.proof1.socProofAttached).to.have.length(1);
expect(proofParams.proof2.socProofAttached).to.have.length(1);
expect(proofParams.proofLast.socProofAttached).to.have.length(1);
expect(proofParams.proof1.socProof).to.have.length(1);
expect(proofParams.proof2.socProof).to.have.length(1);
expect(proofParams.proofLast.socProof).to.have.length(1);
const tx2 = await r_node_5.claim(proofParams.proof1, proofParams.proof2, proofParams.proofLast);
await claimEventChecks(tx2, sampleHashString, hexlify(depth));
});
Expand Down Expand Up @@ -1054,7 +1056,8 @@ describe('Redistribution', function () {
const { proofParams } = await generatedSampling(true);

// alter the identifier into random one
proofParams.proof1.socProofAttached![0].identifier = randomBytes(32);
proofParams.proof1.socProof![0].identifier = randomBytes(32);

await expect(
r_node_5.claim(proofParams.proof1, proofParams.proof2, proofParams.proofLast)
).to.be.revertedWith(errors.claim.socVerificationFailed);
Expand All @@ -1063,8 +1066,8 @@ describe('Redistribution', function () {
it('SOC attachment does not match with witness', async function () {
const { proofParams } = await generatedSampling(true);

proofParams.proof1.socProofAttached![0] = await getSocProofAttachment(
proofParams.proof1.socProofAttached![0].chunkAddr,
proofParams.proof1.socProof![0] = await getSocProofAttachment(
proofParams.proof1.socProof![0].chunkAddr,
randomBytes(32),
depth
);
Expand All @@ -1079,9 +1082,9 @@ describe('Redistribution', function () {
it('stamp index is out of range', async function () {
const { proofParams } = await generatedSampling();

const index = Buffer.from(proofParams.proof1.index);
const index = Buffer.from(proofParams.proof1.postageProof.index);
index.writeUInt32BE(2 ** 30, 4);
proofParams.proof1.index = index;
proofParams.proof1.postageProof.index = index;

await expect(
r_node_5.claim(proofParams.proof1, proofParams.proof2, proofParams.proofLast)
Expand Down Expand Up @@ -1113,10 +1116,10 @@ describe('Redistribution', function () {
const chunkAddr = Buffer.from(proofParams.proof1.proveSegment);
const { index, signature, timeStamp } = await constructPostageStamp(batchId, chunkAddr, wallet);

proofParams.proof1.postageId = batchId;
proofParams.proof1.signature = signature;
proofParams.proof1.index = index;
proofParams.proof1.timeStamp = timeStamp;
proofParams.proof1.postageProof.postageId = batchId;
proofParams.proof1.postageProof.signature = signature;
proofParams.proof1.postageProof.index = index;
proofParams.proof1.postageProof.timeStamp = timeStamp;

await expect(
r_node_5.claim(proofParams.proof1, proofParams.proof2, proofParams.proofLast)
Expand All @@ -1126,9 +1129,9 @@ describe('Redistribution', function () {
it('postage bucket and address bucket do not match', async function () {
const { proofParams } = await generatedSampling();

const index = Buffer.from(proofParams.proof1.index);
const index = Buffer.from(proofParams.proof1.postageProof.index);
index.writeUInt32BE(0, 0);
proofParams.proof1.index = index;
proofParams.proof1.postageProof.index = index;

await expect(
r_node_5.claim(proofParams.proof1, proofParams.proof2, proofParams.proofLast)
Expand All @@ -1138,9 +1141,9 @@ describe('Redistribution', function () {
it('wrong postage stamp signature', async function () {
const { proofParams } = await generatedSampling();

const index = Buffer.from(proofParams.proof1.index);
const index = Buffer.from(proofParams.proof1.postageProof.index);
index.writeUInt32BE(1, 4);
proofParams.proof1.index = index;
proofParams.proof1.postageProof.index = index;

await expect(
r_node_5.claim(proofParams.proof1, proofParams.proof2, proofParams.proofLast)
Expand Down
Loading

0 comments on commit e9d59c9

Please sign in to comment.