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

optimized finalized block #47

Merged
merged 15 commits into from
Jul 22, 2024
139 changes: 72 additions & 67 deletions contracts/FullCheckpoint.sol
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ contract FullCheckpoint {
bytes32 transactionsRoot;
bytes32 receiptRoot;
bytes32 parentHash;
uint256 mix; // padding 64 | uint64 number | uint64 roundNum | uint64 mainnetNum
uint256 mix; // padding 64 | uint64 number | uint64 roundNum | empty
}

struct HeaderInfo {
Expand All @@ -31,8 +31,16 @@ contract FullCheckpoint {
int256 number;
}

struct Range {
uint256 lastFinalizedNumber;
uint256 latestFinalizedNumber;
}
GalaxySciTech marked this conversation as resolved.
Show resolved Hide resolved

Range[] public finalizedRanges;

mapping(bytes32 => Header) private headerTree;
mapping(int256 => bytes32) private committedBlocks;
mapping(uint64 => bytes32) private heightTree;

mapping(address => bool) private lookup;
mapping(address => bool) private uniqueAddr;
mapping(int256 => Validators) private validators;
Expand Down Expand Up @@ -106,13 +114,21 @@ contract FullCheckpoint {
parentHash: gapBlock.parentHash,
mix: (uint256(gapBlock.number) << 128) |
(uint256(gapBlock.roundNumber) << 64) |
uint256(block.number)
0
});

heightTree[uint64(uint256(gapBlock.number))] = gapHeaderHash;

setLookup(initialValidatorSet);
latestBlock = gapHeaderHash;
latestFinalizedBlock = gapHeaderHash;
committedBlocks[gapBlock.number] = gapHeaderHash;
finalizedRanges.push(
Range({
lastFinalizedNumber: 0,
latestFinalizedNumber: uint256(gapBlock.number)
})
);

INIT_GAP = initGap;
INIT_EPOCH = initEpoch;
INIT_STATUS = 1;
Expand Down Expand Up @@ -254,8 +270,9 @@ contract FullCheckpoint {
parentHash: validationParams.parentHash,
mix: (uint256(validationParams.number) << 128) |
(uint256(validationParams.roundNumber) << 64) |
uint256(uint64(int64(-1)))
0
});
heightTree[uint64(uint256(validationParams.number))] = blockHash;
emit SubnetBlockAccepted(blockHash, validationParams.number);
if (
validationParams.number >
Expand All @@ -269,10 +286,10 @@ contract FullCheckpoint {
blockHash
);
if (!isCommitted) continue;
latestFinalizedBlock = committedBlock;

// Confirm all ancestor unconfirmed block
setCommittedStatus(committedBlock);
latestFinalizedBlock = committedBlock;
}
}

Expand All @@ -285,30 +302,21 @@ contract FullCheckpoint {
}
}

/* @dev Confirm all ancestor uncommitted block
if mainnetNum is -1, it means the block is uncommitted.
if mainnetNum is not -1, it means the block is committed.
* @param startBlock
/* @dev Confirm all ancestor uncommitted block
* @param committedBlock
* @return void
*/
function setCommittedStatus(bytes32 startBlock) internal {
while (
int64(uint64(headerTree[startBlock].mix)) == -1 && startBlock != 0
) {
headerTree[startBlock].mix = HeaderReader.clearLowest(
headerTree[startBlock].mix,
64
);
headerTree[startBlock].mix |= block.number;
committedBlocks[
int256(uint256(uint64(headerTree[startBlock].mix >> 128)))
] = startBlock;
emit SubnetBlockFinalized(
startBlock,
int256(uint256(uint64(headerTree[startBlock].mix >> 128)))
);
startBlock = headerTree[startBlock].parentHash;
}
function setCommittedStatus(bytes32 committedBlock) internal {
finalizedRanges.push(
Range({
lastFinalizedNumber: uint256(
uint64(headerTree[latestFinalizedBlock].mix >> 128)
),
latestFinalizedNumber: uint256(
uint64(headerTree[committedBlock].mix >> 128)
)
})
);
}

function checkUniqueness(
Expand Down Expand Up @@ -373,19 +381,20 @@ contract FullCheckpoint {
})
);
}
bool finalized = false;
if (int64(uint64(headerTree[blockHash].mix)) != -1) {
finalized = true;
}

(int256 finalizedNumber, bool isFinalized) = getFinalizedInfo(
blockHash
);

return
HeaderInfo({
parentHash: headerTree[blockHash].parentHash,
number: int256(
uint256(uint64(headerTree[blockHash].mix >> 128))
),
roundNum: uint64(headerTree[blockHash].mix >> 64),
mainnetNum: int64(uint64(headerTree[blockHash].mix)),
finalized: finalized
mainnetNum: int64(finalizedNumber),
finalized: isFinalized
});
}

Expand Down Expand Up @@ -413,43 +422,39 @@ contract FullCheckpoint {

/*
* @param subnet block number.
* @return BlockLite struct defined above.
* @return HeaderInfo struct defined above.
*/
function getHeaderByNumber(
int256 number
) public view returns (BlockLite memory) {
if (committedBlocks[number] == 0) {
int256 blockNum = int256(
uint256(uint64(headerTree[latestBlock].mix >> 128))
);
if (number > blockNum) {
return BlockLite({hash: bytes32(0), number: 0});
}
int256 numGap = blockNum - number;
bytes32 currHash = latestBlock;
for (int256 i = 0; i < numGap; i++) {
currHash = headerTree[currHash].parentHash;
uint256 number
) public view returns (HeaderInfo memory) {
return getHeader(heightTree[uint64(number)]);
}

/**
* @dev Get the finalized information of a block.
* @param blockHash The hash of the block.
* @return finalizedNumber The number of the block.
* @return isFinalized Whether the block is finalized.
*/
function getFinalizedInfo(
bytes32 blockHash
) public view returns (int256 finalizedNumber, bool isFinalized) {
uint256 blockNumber = uint256(uint64(headerTree[blockHash].mix >> 128));
if (blockNumber != 0) {
for (uint256 i = 0; i < finalizedRanges.length; i++) {
GalaxySciTech marked this conversation as resolved.
Show resolved Hide resolved
if (
blockNumber > finalizedRanges[i].lastFinalizedNumber &&
blockNumber <= finalizedRanges[i].latestFinalizedNumber
) {
return (
int256(finalizedRanges[i].latestFinalizedNumber),
true
);
}
GalaxySciTech marked this conversation as resolved.
Show resolved Hide resolved
}
return
BlockLite({
hash: currHash,
number: int256(
uint256(uint64(headerTree[currHash].mix >> 128))
)
});
} else {
return
BlockLite({
hash: committedBlocks[number],
number: int256(
uint256(
uint64(
headerTree[committedBlocks[number]].mix >> 128
)
)
)
});
}

return (-1, false);
}

/*
Expand Down
32 changes: 2 additions & 30 deletions contracts/LiteCheckpoint.sol
Original file line number Diff line number Diff line change
Expand Up @@ -384,36 +384,8 @@ contract LiteCheckpoint {
*/
function getHeaderByNumber(
uint256 number
) public view returns (HeaderInfo memory, bytes32) {
if (heightTree[uint64(number)] != 0) {
bytes32 blockHash = heightTree[uint64(number)];

bool finalized = false;
if (int64(uint64(headerTree[blockHash])) != -1) {
finalized = true;
}
return (
HeaderInfo({
parentHash: 0,
number: uint64(headerTree[blockHash] >> 128),
roundNum: uint64(headerTree[blockHash] >> 64),
mainnetNum: int64(uint64(headerTree[blockHash])),
finalized: finalized
}),
blockHash
);
} else {
return (
HeaderInfo({
parentHash: 0,
number: 0,
roundNum: 0,
mainnetNum: -1,
finalized: false
}),
0
);
}
) public view returns (HeaderInfo memory) {
return getHeader(heightTree[uint64(number)]);
}

function getCurrentEpochBlockByIndex(
Expand Down
Loading
Loading