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

Rename block classes #19

Open
wants to merge 15 commits into
base: main
Choose a base branch
from
8 changes: 4 additions & 4 deletions local-network/deploy/src/waves-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export type LibraryWavesApi = ReturnType<typeof waves.create>;
export type ExtendedWavesApi = LibraryWavesApi & { base: string };
export type WavesSignedTransaction = SignedTransaction<any> & { id: string };

export interface EcBlockContractInfo {
export interface BlockContractInfo {
chainHeight: number,
epochNumber: number
}
Expand Down Expand Up @@ -126,7 +126,7 @@ export async function signAndBroadcast(wavesApi: ExtendedWavesApi, name: string,
if (options.wait) await waitForTxn(wavesApi, id).then(x => logger.debug(`Sent %O result: %O`, unsignedTxJson, x));
}

function parseBlockMeta(response: object): EcBlockContractInfo {
function parseBlockMeta(response: object): BlockContractInfo {
// @ts-ignore: Property 'value' does not exist on type 'object'.
const rawMeta = response.result.value;
return {
Expand All @@ -135,7 +135,7 @@ function parseBlockMeta(response: object): EcBlockContractInfo {
};
}

export async function waitForEcBlock(wavesApi: LibraryWavesApi, chainContractAddress: string, blockHash: string): Promise<EcBlockContractInfo> {
export async function waitForBlock(wavesApi: LibraryWavesApi, chainContractAddress: string, blockHash: string): Promise<BlockContractInfo> {
const getBlockData = async () => {
try {
return parseBlockMeta(await wavesApi.utils.fetchEvaluate(chainContractAddress, `blockMeta("${blockHash.slice(2)}")`));
Expand Down Expand Up @@ -168,7 +168,7 @@ export function prepareE2CWithdrawTxnJson(
};
}

export async function chainContractCurrFinalizedBlock(wavesApi: LibraryWavesApi, chainContractAddress: string): Promise<EcBlockContractInfo> {
export async function chainContractCurrFinalizedBlock(wavesApi: LibraryWavesApi, chainContractAddress: string): Promise<BlockContractInfo> {
// @ts-ignore: Property 'value' does not exist on type 'object'.
return parseBlockMeta(await wavesApi.utils.fetchEvaluate(chainContractAddress, `blockMeta(getStringValue("finalizedBlock"))`));
}
23 changes: 0 additions & 23 deletions local-network/deploy/test/miner_big-join.ts

This file was deleted.

2 changes: 1 addition & 1 deletion local-network/deploy/test/transfer-e2c.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ if (rawLogsInBlock.length == 0) throw new Error(`Can't find logs in ${blockHash}
const logsInBlock = rawLogsInBlock as Exclude<typeof rawLogsInBlock[number], string>[];

logger.info(`Waiting EL block ${blockHash} confirmation on CL`);
const withdrawBlockMeta = await waves.utils.waitForEcBlock(waves.wavesApi1, waves.chainContractAddress, blockHash);
const withdrawBlockMeta = await waves.utils.waitForBlock(waves.wavesApi1, waves.chainContractAddress, blockHash);
logger.info(`Withdraw block meta: %O`, withdrawBlockMeta);

let rawData: string[] = [];
Expand Down
468 changes: 233 additions & 235 deletions src/main/scala/units/ELUpdater.scala

Large diffs are not rendered by default.

99 changes: 99 additions & 0 deletions src/main/scala/units/NetworkBlock.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
package units
vsuharnikov marked this conversation as resolved.
Show resolved Hide resolved

import cats.syntax.either.*
import com.wavesplatform.account.PrivateKey
import com.wavesplatform.common.state.ByteStr
import com.wavesplatform.crypto
import com.wavesplatform.crypto.{DigestLength, SignatureLength}
import org.web3j.abi.datatypes.generated.Uint256
import play.api.libs.json.{JsObject, Json}
import units.client.CommonBlockData
import units.client.engine.model.{ExecutionPayload, Withdrawal}
import units.eth.EthAddress
import units.util.HexBytesConverter.*

// TODO Refactor to eliminate a manual deserialization, e.g. (raw: JsonObject, parsed: ParsedBlockL2)
class NetworkBlock private (
val hash: BlockHash,
val timestamp: Long, // UNIX epoch seconds
val height: Long,
val parentHash: BlockHash,
val stateRoot: String,
val minerRewardAddress: EthAddress,
val baseFeePerGas: Uint256,
val gasLimit: Long,
val gasUsed: Long,
val prevRandao: String,
val withdrawals: Vector[Withdrawal],
val payloadBytes: Array[Byte],
val payloadJson: JsObject,
val signature: Option[ByteStr]
) extends CommonBlockData {
def isEpochFirstBlock: Boolean = withdrawals.nonEmpty

def toPayload: ExecutionPayload = ExecutionPayload(
hash = hash,
parentHash = parentHash,
stateRoot = stateRoot,
height = height,
timestamp = timestamp,
minerRewardAddress = minerRewardAddress,
baseFeePerGas = baseFeePerGas,
gasLimit = gasLimit,
gasUsed = gasUsed,
prevRandao = prevRandao,
withdrawals = withdrawals
)

override def toString: String = s"NetworkBlock($hash)"
}

object NetworkBlock {
private def apply(payload: JsObject, payloadBytes: Array[Byte], signature: Option[ByteStr]): Either[ClientError, NetworkBlock] = {
// See BlockToPayloadMapper for all available fields
(for {
hash <- (payload \ "blockHash").asOpt[BlockHash].toRight("hash not defined")
timestamp <- (payload \ "timestamp").asOpt[String].map(toLong).toRight("timestamp not defined")
height <- (payload \ "blockNumber").asOpt[String].map(toLong).toRight("height not defined")
parentHash <- (payload \ "parentHash").asOpt[BlockHash].toRight("parent hash not defined")
stateRoot <- (payload \ "stateRoot").asOpt[String].toRight("state root not defined")
minerRewardAddress <- (payload \ "feeRecipient").asOpt[EthAddress].toRight("fee recipient not defined")
baseFeePerGas <- (payload \ "baseFeePerGas").asOpt[String].map(toUint256).toRight("baseFeePerGas not defined")
gasLimit <- (payload \ "gasLimit").asOpt[String].map(toLong).toRight("gasLimit not defined")
gasUsed <- (payload \ "gasUsed").asOpt[String].map(toLong).toRight("gasUsed not defined")
prevRandao <- (payload \ "prevRandao").asOpt[String].toRight("prevRandao not defined")
withdrawals <- (payload \ "withdrawals").asOpt[Vector[Withdrawal]].toRight("withdrawals are not defined")
_ <- Either.cond(signature.forall(_.size == SignatureLength), (), "invalid signature size")
} yield new NetworkBlock(
hash,
timestamp,
height,
parentHash,
stateRoot,
minerRewardAddress,
baseFeePerGas,
gasLimit,
gasUsed,
prevRandao,
withdrawals,
payloadBytes,
payload,
signature
)).leftMap(err => ClientError(s"Error creating NetworkBlock from payload ${new String(payloadBytes)}: $err at payload"))
}

def apply(payloadBytes: Array[Byte], signature: Option[ByteStr]): Either[ClientError, NetworkBlock] = for {
payload <- Json.parse(payloadBytes).asOpt[JsObject].toRight(ClientError("Payload is not a valid JSON object"))
block <- apply(payload, payloadBytes, signature)
} yield block

def signed(payload: JsObject, signer: PrivateKey): Either[ClientError, NetworkBlock] = {
val payloadBytes = Json.toBytes(payload)
NetworkBlock(payload, payloadBytes, Some(crypto.sign(signer, payloadBytes)))
}

def apply(payload: JsObject): Either[ClientError, NetworkBlock] = apply(payload, Json.toBytes(payload), None)

def validateReferenceLength(length: Int): Boolean =
length == DigestLength
}
99 changes: 0 additions & 99 deletions src/main/scala/units/NetworkL2Block.scala

This file was deleted.

13 changes: 13 additions & 0 deletions src/main/scala/units/client/CommonBlockData.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package units.client

import units.BlockHash
import units.eth.{EthAddress, EthereumConstants}

trait CommonBlockData {
def hash: BlockHash
def parentHash: BlockHash
def height: Long
def minerRewardAddress: EthAddress

def referencesGenesis: Boolean = height == EthereumConstants.GenesisBlockHeight + 1
}
18 changes: 0 additions & 18 deletions src/main/scala/units/client/L2BlockLike.scala

This file was deleted.

22 changes: 11 additions & 11 deletions src/main/scala/units/client/contract/ContractBlock.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,22 @@ package units.client.contract

import com.wavesplatform.common.merkle.Digest
import units.BlockHash
import units.client.L2BlockLike
import units.client.CommonBlockData
import units.eth.EthAddress
import units.util.HexBytesConverter.toHex

case class ContractBlock(
hash: BlockHash,
parentHash: BlockHash,
epoch: Int,
height: Long,
minerRewardL2Address: EthAddress,
chainId: Long,
e2cTransfersRootHash: Digest,
lastC2ETransferIndex: Long
) extends L2BlockLike {
hash: BlockHash,
parentHash: BlockHash,
epoch: Int,
height: Long,
minerRewardAddress: EthAddress,
chainId: Long,
e2cTransfersRootHash: Digest,
lastC2ETransferIndex: Long
vsuharnikov marked this conversation as resolved.
Show resolved Hide resolved
) extends CommonBlockData {
override def toString: String =
s"ContractBlock($hash, p=$parentHash, e=$epoch, h=$height, m=$minerRewardL2Address, c=$chainId, " +
s"ContractBlock($hash, p=$parentHash, e=$epoch, h=$height, m=$minerRewardAddress, c=$chainId, " +
s"e2c=${if (e2cTransfersRootHash.isEmpty) "" else toHex(e2cTransfersRootHash)}, c2e=$lastC2ETransferIndex)"
}

Expand Down
16 changes: 8 additions & 8 deletions src/main/scala/units/client/engine/EngineApiClient.scala
Original file line number Diff line number Diff line change
Expand Up @@ -18,21 +18,21 @@ trait EngineApiClient {
withdrawals: Vector[Withdrawal] = Vector.empty
): JobResult[PayloadId]

def getPayload(payloadId: PayloadId): JobResult[JsObject]
def getPayloadJson(payloadId: PayloadId): JobResult[JsObject]

def applyNewPayload(payload: JsObject): JobResult[Option[BlockHash]]
def applyNewPayload(payloadJson: JsObject): JobResult[Option[BlockHash]]

def getPayloadBodyByHash(hash: BlockHash): JobResult[Option[JsObject]]
def getPayloadBodyJsonByHash(hash: BlockHash): JobResult[Option[JsObject]]

def getBlockByNumber(number: BlockNumber): JobResult[Option[EcBlock]]
def getPayloadByNumber(number: BlockNumber): JobResult[Option[ExecutionPayload]]

def getBlockByHash(hash: BlockHash): JobResult[Option[EcBlock]]
def getPayloadByHash(hash: BlockHash): JobResult[Option[ExecutionPayload]]

def getBlockByHashJson(hash: BlockHash): JobResult[Option[JsObject]]
def getLastPayload: JobResult[ExecutionPayload]

def getLastExecutionBlock: JobResult[EcBlock]
def getBlockJsonByHash(hash: BlockHash): JobResult[Option[JsObject]]

def blockExists(hash: BlockHash): JobResult[Boolean]
def getPayloadJsonDataByHash(hash: BlockHash): JobResult[PayloadJsonData]

def getLogs(hash: BlockHash, address: EthAddress, topic: String): JobResult[List[GetLogsResponseEntry]]
}
Expand Down
Loading