Skip to content

Commit

Permalink
Merge branch 'main' of github.com:originalworks/protocol
Browse files Browse the repository at this point in the history
  • Loading branch information
criadoperez committed Oct 4, 2024
2 parents e679f23 + 5e0f713 commit 08de5cb
Show file tree
Hide file tree
Showing 17 changed files with 404 additions and 36 deletions.
13 changes: 11 additions & 2 deletions contracts/contracts/DdexSequencer.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,19 @@ pragma solidity ^0.8.24;

contract DdexSequencer is WhitelistConsumer {
event NewBlobSubmitted(bytes commitment);

event MessageDigested(DdexMessageData data);

struct Blob {
bytes32 nextBlob;
bool submitted;
address proposer;
}

struct DdexMessageData {
string isrc;
string releaseId;
}

bytes1 public constant DATA_PROVIDERS_WHITELIST = 0x01;
bytes1 public constant VALIDATORS_WHITELIST = 0x02;

Expand Down Expand Up @@ -59,14 +64,18 @@ contract DdexSequencer is WhitelistConsumer {
}

function submitProofOfProcessing(
bool proof
bool proof,
DdexMessageData[] memory messagesData
) external isWhitelistedOn(VALIDATORS_WHITELIST) {
require(blobQueueHead != bytes32(0), "Queue is empty");
bool isValid = proof; // TODO: implement actual logic of checking the proof for the blobQueueHead

require(isValid, "Invalid proof");

_moveQueue();
for (uint i = 0; i < messagesData.length; i++) {
emit MessageDigested(messagesData[i]);
}
}

function submitProofForFraudulentBlob(
Expand Down
47 changes: 47 additions & 0 deletions contracts/scripts/execute/deployLocal.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { deployDdexSequencer } from "../actions/contract-deployment/DdexSequencer/DdexSequencer.deploy";
import { deployOwnToken } from "../actions/contract-deployment/OwnToken/OwnToken.deploy";
import { deployStakeVault } from "../actions/contract-deployment/StakeVault/StakeVault.deploy";
import { deployWhitelist } from "../actions/contract-deployment/Whitelist/Whitelist.deploy";
import { ethers } from "hardhat";
import { getKurtosisEthersWallets } from "../fixture/fixture.deploy";

const SLASH_RATE = 1000;

async function main() {
const [signer, validator, validator2, dataProvider, dataProvider2] =
getKurtosisEthersWallets();

const dataProvidersWhitelist = await deployWhitelist(signer, [
dataProvider.address,
dataProvider2.address,
]);
const validatorsWhitelist = await deployWhitelist(signer, [
validator.address,
validator2.address,
]);
const ownToken = await deployOwnToken();
const stakeVault = await deployStakeVault({
stakeTokenAddress: await ownToken.getAddress(),
_slashRate: SLASH_RATE,
});
const ddexSequencer = await deployDdexSequencer({
dataProvidersWhitelist: await dataProvidersWhitelist.getAddress(),
validatorsWhitelist: await validatorsWhitelist.getAddress(),
stakeVaultAddress: await stakeVault.getAddress(),
});

console.log({
token: await ownToken.getAddress(),
deployer: await signer.getAddress(),
validator: validator.address,
validator2: validator2.address,
dataProvider: dataProvider.address,
dataProvider2: dataProvider2.address,
ddexSequencer: await ddexSequencer.getAddress(),
ownToken: await ownToken.getAddress(),
dataProvidersWhitelist: await dataProvidersWhitelist.getAddress(),
validatorsWhitelist: await validatorsWhitelist.getAddress(),
});
}

main();
18 changes: 18 additions & 0 deletions contracts/scripts/fixture/fixture.deploy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,21 @@ export async function getEthersWalletWithFunds(
await tx.wait();
return wallet;
}

// it's necessary to use ethers.Wallet instead of hardhatEthers.Wallet
// as only the first one currently supports type 3 EIP4844 transaction
// This function works only with Kurtosis testnet setup!!!!
export function getKurtosisEthersWallets(): HDNodeWallet[] {
const phrase = `${process.env.KURTOSIS_MNEMONIC}`;
const mnemonic = ethers.Mnemonic.fromPhrase(phrase);
const wallets: HDNodeWallet[] = [];
for (let i = 0; i < 20; i++) {
wallets.push(
ethers.HDNodeWallet.fromMnemonic(mnemonic, `m/44'/60'/0'/0/${i}`).connect(
hardhatEthers.provider
)
);
}

return wallets;
}
17 changes: 9 additions & 8 deletions contracts/test/DdexSequencer.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ describe("DdexSequencer", () => {
expect(await ddexSequencer.blobQueueTail()).equal(blobhash);

const blobDetailsBefore = await ddexSequencer.blobs(blobhash);
await ddexSequencer.connect(validator).submitProofOfProcessing(true);
await ddexSequencer.connect(validator).submitProofOfProcessing(true, []);
const blobDetailsAfter = await ddexSequencer.blobs(blobhash);

expect(await ddexSequencer.blobQueueHead()).equal(ZERO_BYTES32);
Expand Down Expand Up @@ -176,7 +176,7 @@ describe("DdexSequencer", () => {
expect(await ddexSequencer.blobQueueTail()).equal(blobhash2);

const blob1DetailsBefore = await ddexSequencer.blobs(blobhash1);
await ddexSequencer.connect(validator).submitProofOfProcessing(true);
await ddexSequencer.connect(validator).submitProofOfProcessing(true, []);
const blob1DetailsAfter = await ddexSequencer.blobs(blobhash1);

expect(blob1DetailsBefore.nextBlob).equal(blobhash2);
Expand All @@ -191,7 +191,7 @@ describe("DdexSequencer", () => {
expect(await ddexSequencer.blobQueueHead()).equal(blobhash2);
expect(await ddexSequencer.blobQueueTail()).equal(blobhash2);
const blob2DetailsBefore = await ddexSequencer.blobs(blobhash2);
await ddexSequencer.connect(validator).submitProofOfProcessing(true);
await ddexSequencer.connect(validator).submitProofOfProcessing(true, []);
const blob2DetailsAfter = await ddexSequencer.blobs(blobhash2);

expect(blob2DetailsBefore.nextBlob).equal(ZERO_BYTES32);
Expand Down Expand Up @@ -237,7 +237,7 @@ describe("DdexSequencer", () => {
expect(await ddexSequencer.blobQueueTail()).equal(blobhash3);

const blob1DetailsBefore = await ddexSequencer.blobs(blobhash1);
await ddexSequencer.connect(validator).submitProofOfProcessing(true);
await ddexSequencer.connect(validator).submitProofOfProcessing(true, []);
const blob1DetailsAfter = await ddexSequencer.blobs(blobhash1);

expect(blob1DetailsBefore.nextBlob).equal(blobhash2);
Expand All @@ -252,7 +252,7 @@ describe("DdexSequencer", () => {
expect(await ddexSequencer.blobQueueHead()).equal(blobhash2);
expect(await ddexSequencer.blobQueueTail()).equal(blobhash3);
const blob2DetailsBefore = await ddexSequencer.blobs(blobhash2);
await ddexSequencer.connect(validator).submitProofOfProcessing(true);
await ddexSequencer.connect(validator).submitProofOfProcessing(true, []);
const blob2DetailsAfter = await ddexSequencer.blobs(blobhash2);

expect(blob2DetailsBefore.nextBlob).equal(blobhash3);
Expand All @@ -267,7 +267,7 @@ describe("DdexSequencer", () => {
expect(await ddexSequencer.blobQueueHead()).equal(blobhash3);
expect(await ddexSequencer.blobQueueTail()).equal(blobhash3);
const blob3DetailsBefore = await ddexSequencer.blobs(blobhash3);
await ddexSequencer.connect(validator).submitProofOfProcessing(true);
await ddexSequencer.connect(validator).submitProofOfProcessing(true, []);
const blob3DetailsAfter = await ddexSequencer.blobs(blobhash3);

expect(blob3DetailsBefore.nextBlob).equal(ZERO_BYTES32);
Expand All @@ -289,7 +289,8 @@ describe("DdexSequencer", () => {
validators: [validator],
} = fixture;
expect(await ddexSequencer.blobQueueHead()).equal(ZERO_BYTES32);
await expect(ddexSequencer.connect(validator).submitProofOfProcessing(true))
.to.rejected;
await expect(
ddexSequencer.connect(validator).submitProofOfProcessing(true, [])
).to.rejected;
});
});
2 changes: 1 addition & 1 deletion ow_data_provider_cli/src/constants.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
use alloy::primitives::{address, Address};

pub const DDEX_SEQUENCER_ADDRESS: Address = address!("00c042C4D5D913277CE16611a2ce6e9003554aD5");
pub const DDEX_SEQUENCER_ADDRESS: Address = address!("B965D10739e19a9158e7f713720B0145D996E370");
4 changes: 4 additions & 0 deletions ow_data_provider_cli/src/ddex_sequencer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,10 @@ impl DdexSequencerContext<'_> {
.contract
.submitNewBlob(Bytes::from(transaction_data.kzg_commitment.to_vec()))
.sidecar(transaction_data.blob_sidecar)
// TODO make gas settings optional CLI/setting file parameters
.max_fee_per_blob_gas(10000000)
.max_fee_per_gas(100000000)
.max_priority_fee_per_gas(100000000)
.send()
.await
.unwrap()
Expand Down
1 change: 1 addition & 0 deletions ow_data_provider_cli/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ pub async fn run(config: Config) -> Result<(), Box<dyn Error>> {

let ddex_sequencer_context = DdexSequencerContext::build(&provider).await?;
let blob_transaction_data = BlobTransactionData::build(&config).unwrap();
println!("sending tx...");
ddex_sequencer_context
.send_blob(blob_transaction_data)
.await?;
Expand Down
1 change: 1 addition & 0 deletions ow_validator_node/.env.template
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
PRIVATE_KEY=0000000000000000000000000000000000000000000000000000000000000000
RPC_URL=https://placeholder
WS_URL=wss://placeholder
BEACON_RPC_URL=placeholder
Expand Down
39 changes: 38 additions & 1 deletion ow_validator_node/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions ow_validator_node/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ edition = "2021"
alloy = { version = "0.3.0", features = ["full"] }
dotenvy = "0.15.7"
futures-util = "0.3.30"
ow_blob_codec = "0.1.1"
quick-xml = "0.36.2"
reqwest = "0.12.7"
serde = { version = "1.0.210", features = ["derive"] }
sha2 = "0.10.8"
Expand Down
10 changes: 7 additions & 3 deletions ow_validator_node/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,20 @@

This is still very much pre-alfa early stage sketch-draft prototype!!!

This package will simply read the BLOB assigned to the message head in the DdexSequencer queue.
This package currently do:

1. Read the BLOB associated with queue head of the `DdexSequencer`
2. Decode the BLOB and use `circuit_mock` to extract `isrc` and `GRid`
3. Send `isrc` and `GRid` as events to `DdexSequencer`

### TODO:

- Observe DDEX MESSAGE SEQUENCER contract and listen to the events
- ~~Observe DDEX MESSAGE SEQUENCER contract and listen to the events~~
- check if there is an access on IPFS to the added CID of graphic files inside DDEX message
- BLOB processing:
- create ZK proof for either successful BLOB processing or for incompatible BLOB
- extract key data from DDEX messages packed into the BLOB
- pin BLOB to IPFS
- pin each DDEX message to IPFS
- prepare and send transaction to DDEX MESSAGE SEQUENCER
- ~~prepare and send transaction to DDEX MESSAGE SEQUENCER~~
- tests!
33 changes: 30 additions & 3 deletions ow_validator_node/src/beacon_chain.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
use crate::{constants, errors::OwValidatorNodeError};
use alloy::primitives::{Bytes, FixedBytes};
use alloy::{
eips::eip4844::BYTES_PER_BLOB,
primitives::{Bytes, FixedBytes},
};
use reqwest;
use serde::Deserialize;
use std::error::Error;
Expand Down Expand Up @@ -81,11 +84,32 @@ async fn find_commitment_in_sidecars(
}
}

fn blob_vec_from_string(prefixed_blob: String) -> Result<[u8; BYTES_PER_BLOB], Box<dyn Error>> {
if prefixed_blob.len() != BYTES_PER_BLOB * 2 + 2 {
return Err(Box::new(OwValidatorNodeError::InvalidBlobLength(
prefixed_blob.len(),
)));
}
let mut byte_array = [0u8; BYTES_PER_BLOB];

let blob = &prefixed_blob[2..];

for (i, byte) in byte_array.iter_mut().enumerate() {
let hex_byte = &blob[i * 2..i * 2 + 2];
*byte = u8::from_str_radix(hex_byte, 16).map_err(|_| {
Box::new(OwValidatorNodeError::InvalidHexStringValue(
hex_byte.to_string(),
))
})?;
}
Ok(byte_array)
}

pub async fn find_blob(
beacon_rpc_url: &String,
commitment: Bytes,
parent_beacon_block_root: FixedBytes<32>,
) -> Result<String, Box<dyn Error>> {
) -> Result<[u8; BYTES_PER_BLOB], Box<dyn Error>> {
let mut slot = get_parent_beacon_block_slot(beacon_rpc_url, parent_beacon_block_root).await?;
let mut blob_sidecar_data: Option<BlobSidecarData> =
find_commitment_in_sidecars(beacon_rpc_url, slot, &commitment).await;
Expand All @@ -102,5 +126,8 @@ pub async fn find_blob(
));
})?
.blob;
Ok(blob)

let blob_array = blob_vec_from_string(blob)?;

Ok(blob_array)
}
Loading

0 comments on commit 08de5cb

Please sign in to comment.