Skip to content

Commit

Permalink
Merge pull request #71 from pshenmic/feat/owners
Browse files Browse the repository at this point in the history
Add data contracts and document owners
  • Loading branch information
pshenmic authored Oct 26, 2023
2 parents 5fd1a61 + aa1a342 commit 1025187
Show file tree
Hide file tree
Showing 6 changed files with 93 additions and 35 deletions.
5 changes: 5 additions & 0 deletions packages/indexer/migrations/V16__add_data_contract_owner.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
ALTER TABLE data_contracts
ADD COLUMN "state_transition_hash" char(64) not null;

ALTER TABLE data_contracts
ADD COLUMN "owner" char(44) not null;
2 changes: 2 additions & 0 deletions packages/indexer/migrations/V17__add_document_owner.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
ALTER TABLE documents
ADD COLUMN "owner" char(44) not null;
15 changes: 9 additions & 6 deletions packages/indexer/src/entities/data_contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use dpp::data_contract::serialized_version::DataContractInSerializationFormat;
use dpp::data_contracts::SystemDataContract;
use dpp::identifier::Identifier;
use dpp::platform_value::string_encoding::Encoding;
use dpp::platform_value::string_encoding::Encoding::Base58;
use dpp::state_transition::data_contract_create_transition::DataContractCreateTransition;
use dpp::state_transition::data_contract_update_transition::DataContractUpdateTransition;
use serde_json::Value;
Expand All @@ -24,12 +25,12 @@ impl From<DataContractCreateTransition> for DataContract {

match data_contract {
DataContractInSerializationFormat::V0(data_contract) => {
let id = data_contract.id;
let identifier = data_contract.id;
let version = data_contract.version;
let schema = data_contract.document_schemas;
let schema_decoded = serde_json::to_value(schema).unwrap();

return DataContract{ id: None, identifier: id, schema: Some(schema_decoded), version };
return DataContract{ id: None, identifier, schema: Some(schema_decoded), version };
}
}
}
Expand All @@ -46,12 +47,13 @@ impl From<DataContractUpdateTransition> for DataContract {

match data_contract {
DataContractInSerializationFormat::V0(data_contract) => {
let id = data_contract.id;
let identifier = data_contract.id;
let owner = data_contract.owner_id;
let version = data_contract.version;
let schema = data_contract.document_schemas;
let schema_decoded = serde_json::to_value(schema).unwrap();

return DataContract{ id: None, identifier: id, schema: Some(schema_decoded), version };
return DataContract{ id: None, identifier, schema: Some(schema_decoded), version };
}
}
}
Expand Down Expand Up @@ -79,11 +81,12 @@ impl From<SystemDataContract> for DataContract {
impl From<Row> for DataContract {
fn from(row: Row) -> Self {
let id: i32 = row.get(0);
let owner: String = row.get(1);

let identifier_str: String = row.get(1);
let identifier_str: String = row.get(2);
let identifier = Identifier::from_string(&identifier_str, Encoding::Base58).unwrap();

let version:i32 = row.get(2);
let version:i32 = row.get(3);

return DataContract{
id: Some(id as u32),
Expand Down
52 changes: 43 additions & 9 deletions packages/indexer/src/entities/document.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use dpp::identifier::Identifier;
use dpp::platform_value::string_encoding::Encoding;
use dpp::platform_value::string_encoding::Encoding::Base58;
use dpp::prelude::Revision;
use dpp::state_transition::documents_batch_transition::document_base_transition::v0::v0_methods::DocumentBaseTransitionV0Methods;
use dpp::state_transition::documents_batch_transition::document_create_transition::v0::v0_methods::DocumentCreateTransitionV0Methods;
Expand All @@ -13,6 +14,7 @@ use tokio_postgres::Row;
pub struct Document {
pub id: Option<u32>,
pub identifier: Identifier,
pub owner: Option<Identifier>,
pub data_contract_identifier: Identifier,
pub data: Option<Value>,
pub deleted: bool,
Expand All @@ -26,14 +28,24 @@ impl From<Row> for Document {
let identifier_str: String = row.get(1);
let identifier = Identifier::from_string(&identifier_str, Encoding::Base58).unwrap();

let data_contract_identifier_str: String = row.get(2);
let owner: String = row.get(2);

let data_contract_identifier_str: String = row.get(3);
let data_contract_identifier = Identifier::from_string(&data_contract_identifier_str, Encoding::Base58).unwrap();

let revision: i32 = row.get(3);
let revision: i32 = row.get(4);

let deleted: bool = row.get(4);
let deleted: bool = row.get(5);

return Document { id: Some(id as u32), deleted, identifier, data: None, data_contract_identifier, revision: Revision::from(revision as u64) };
return Document {
id: Some(id as u32),
deleted,
identifier,
owner: Some(Identifier::from_string(&owner, Base58).unwrap()),
data: None,
data_contract_identifier,
revision: Revision::from(revision as u64),
};
}
}

Expand All @@ -48,7 +60,15 @@ impl From<DocumentTransition> for Document {
let data_contract_identifier = base.data_contract_id();
let revision: Revision = Revision::from(0 as u64);

return Document { id: None, identifier, data: Some(data_decoded), data_contract_identifier, revision, deleted: false };
return Document {
id: None,
owner: None,
identifier,
data: Some(data_decoded),
data_contract_identifier,
revision,
deleted: false,
};
}
DocumentTransition::Replace(transition) => {
let base = transition.base().clone();
Expand All @@ -58,19 +78,33 @@ impl From<DocumentTransition> for Document {
let data_contract_identifier = base.data_contract_id();
let revision = transition.revision();

return Document { id: None, identifier, data: Some(data_decoded), data_contract_identifier, revision, deleted: false };

return Document {
id: None,
owner: None,
identifier,
data: Some(data_decoded),
data_contract_identifier,
revision,
deleted: false,
};
}
DocumentTransition::Delete(transition) => {
let base = transition.base().clone();
let identifier = base.id();
let data_contract_identifier = base.data_contract_id();
let revision: Revision = Revision::from(0 as u64);

return Document { id: None, identifier, data: None, data_contract_identifier, revision, deleted: true };
return Document {
id: None,
owner: None,
identifier,
data: None,
data_contract_identifier,
revision,
deleted: true,
};
}
}

}
}

20 changes: 12 additions & 8 deletions packages/indexer/src/processor/psql/dao/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,25 +53,29 @@ impl PostgresDAO {
println!("Created ST with hash {} from block with hash {}", &hash, &block_hash);
}

pub async fn create_data_contract(&self, data_contract: DataContract) {
pub async fn create_data_contract(&self, data_contract: DataContract, owner: Identifier, st_hash: String) {
let id = data_contract.identifier;
let id_str = id.to_string(Encoding::Base58);
let owner_str = owner.to_string(Encoding::Base58);

let schema = data_contract.schema;
let schema_decoded = serde_json::to_value(schema).unwrap();

let version = data_contract.version as i32;

let query = "INSERT INTO data_contracts(identifier, schema, version) VALUES ($1, $2, $3);";
let query = "INSERT INTO data_contracts(identifier, owner , schema, version, state_transition_hash) VALUES ($1, $2, $3, $4, $5);";

let client = self.connection_pool.get().await.unwrap();
let stmt = client.prepare_cached(query).await.unwrap();
client.query(&stmt, &[&id_str, &schema_decoded, &version]).await.unwrap();

println!("{}", &owner_str.len());

client.query(&stmt, &[&id_str, &owner_str, &schema_decoded, &version, &st_hash]).await.unwrap();

println!("Created DataContract {} [{} version]", id_str, version);
}

pub async fn create_document(&self, document: Document, st_hash: String) -> Result<(), PoolError> {
pub async fn create_document(&self, document: Document, owner: Identifier, st_hash: String) -> Result<(), PoolError> {
let id = document.identifier;
let revision = document.revision;
let revision_i32 = revision as i32;
Expand All @@ -83,11 +87,11 @@ impl PostgresDAO {
let data_contract = self.get_data_contract_by_identifier(document.data_contract_identifier).await.unwrap().unwrap();
let data_contract_id = data_contract.id.unwrap() as i32;

let query = "INSERT INTO documents(identifier,revision,data,deleted,state_transition_hash,data_contract_id) VALUES ($1, $2, $3, $4, $5, $6);";
let query = "INSERT INTO documents(identifier,owner,revision,data,deleted,state_transition_hash,data_contract_id) VALUES ($1, $2, $3, $4, $5, $6,$7);";

let stmt = client.prepare_cached(query).await.unwrap();

client.query(&stmt, &[&id.to_string(Encoding::Base58), &revision_i32, &data, &document.deleted, &st_hash, &data_contract_id]).await.unwrap();
client.query(&stmt, &[&id.to_string(Encoding::Base58), &owner.to_string(Base58), &revision_i32, &data, &document.deleted, &st_hash, &data_contract_id]).await.unwrap();

println!("Created document {} [{} revision] [is_deleted {}]", document.identifier.to_string(Base58), revision_i32, document.deleted);

Expand Down Expand Up @@ -153,7 +157,7 @@ impl PostgresDAO {
pub async fn get_data_contract_by_identifier(&self, identifier: Identifier) -> Result<Option<DataContract>, PoolError> {
let client = self.connection_pool.get().await?;

let stmt = client.prepare_cached("SELECT id,identifier,version FROM data_contracts where identifier = $1 ORDER by version DESC LIMIT 1;").await.unwrap();
let stmt = client.prepare_cached("SELECT id,owner,identifier,version FROM data_contracts where identifier = $1 ORDER by version DESC LIMIT 1;").await.unwrap();

let rows: Vec<Row> = client.query(&stmt, &[&identifier.to_string(Encoding::Base58)])
.await.unwrap();
Expand All @@ -170,7 +174,7 @@ impl PostgresDAO {
pub async fn get_document_by_identifier(&self, identifier: Identifier) -> Result<Option<Document>, PoolError> {
let client = self.connection_pool.get().await?;

let stmt = client.prepare_cached("SELECT id,identifier,revision,deleted FROM documents where identifier = $1 ORDER BY id DESC LIMIT 1;").await.unwrap();
let stmt = client.prepare_cached("SELECT id,identifier,owner,revision,deleted FROM documents where identifier = $1 ORDER BY id DESC LIMIT 1;").await.unwrap();

let rows: Vec<Row> = client.query(&stmt, &[&identifier.to_string(Encoding::Base58)])
.await.unwrap();
Expand Down
34 changes: 22 additions & 12 deletions packages/indexer/src/processor/psql/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use dpp::state_transition::data_contract_create_transition::DataContractCreateTr
use crate::processor::psql::dao::PostgresDAO;
use base64::{Engine as _, engine::{general_purpose}};
use dpp::data_contracts::SystemDataContract;
use dpp::identifier::Identifier;
use dpp::platform_value::string_encoding::Encoding::Base58;
use dpp::serialization::PlatformSerializable;
use dpp::state_transition::documents_batch_transition::accessors::DocumentsBatchTransitionAccessorsV0;
Expand Down Expand Up @@ -64,25 +65,28 @@ impl PSQLProcessor {
return PSQLProcessor { decoder, dao };
}

pub async fn handle_data_contract_create(&self, state_transition: DataContractCreateTransition) -> () {
pub async fn handle_data_contract_create(&self, state_transition: DataContractCreateTransition, st_hash: String) -> () {
let owner = state_transition.owner_id();
let data_contract = DataContract::from(state_transition);

self.dao.create_data_contract(data_contract).await;
self.dao.create_data_contract(data_contract, owner, st_hash).await;
}

pub async fn handle_data_contract_update(&self, state_transition: DataContractUpdateTransition) -> () {
pub async fn handle_data_contract_update(&self, state_transition: DataContractUpdateTransition, st_hash: String) -> () {
let owner = state_transition.owner_id();
let data_contract = DataContract::from(state_transition);

self.dao.create_data_contract(data_contract).await;
self.dao.create_data_contract(data_contract, owner, st_hash).await;
}

pub async fn handle_documents_batch(&self, state_transition: DocumentsBatchTransition, st_hash: String) -> () {
let transitions = state_transition.transitions().clone();
let owner = state_transition.owner_id();

for (_, document_transition) in transitions.iter().enumerate() {
let document = Document::from(document_transition.clone());

self.dao.create_document(document, st_hash.clone()).await;
self.dao.create_document(document, owner, st_hash.clone()).await;
}
}

Expand Down Expand Up @@ -165,16 +169,20 @@ impl PSQLProcessor {

match state_transition {
StateTransition::DataContractCreate(st) => {
let st_hash = digest(bytes.clone()).to_uppercase();

self.dao.create_state_transition(block_hash.clone(), st_type, index, bytes).await;

self.handle_data_contract_create(st).await;
self.handle_data_contract_create(st, st_hash).await;

println!("Processed DataContractCreate at block hash {}", block_hash);
}
StateTransition::DataContractUpdate(st) => {
let st_hash = digest(bytes.clone()).to_uppercase();

self.dao.create_state_transition(block_hash.clone(), st_type, index, bytes).await;

self.handle_data_contract_update(st).await;
self.handle_data_contract_update(st, st_hash).await;

println!("Processed DataContractUpdate at block hash {}", block_hash);
}
Expand Down Expand Up @@ -265,31 +273,33 @@ impl PSQLProcessor {
println!("Processing initChain");

let mut system_contract;
let mut owner;
let mut data_contract;

system_contract = SystemDataContract::Withdrawals;
owner = Identifier::from(system_contract.source().unwrap().owner_id_bytes);
data_contract = DataContract::from(system_contract);
println!("Processing SystemDataContract::Withdrawals {}", data_contract.identifier.to_string(Base58));
self.dao.create_data_contract(data_contract).await;
self.dao.create_data_contract(data_contract, owner, String::from("initChain")).await;

system_contract = SystemDataContract::MasternodeRewards;
data_contract = DataContract::from(system_contract);
println!("Processing SystemDataContract::MasternodeRewards {}", data_contract.identifier.to_string(Base58));
self.dao.create_data_contract(data_contract).await;
self.dao.create_data_contract(data_contract, owner, String::from("initChain")).await;

system_contract = SystemDataContract::FeatureFlags;
data_contract = DataContract::from(system_contract);
println!("Processing SystemDataContract::FeatureFlags {}", data_contract.identifier.to_string(Base58));
self.dao.create_data_contract(data_contract).await;
self.dao.create_data_contract(data_contract, owner, String::from("initChain")).await;

system_contract = SystemDataContract::DPNS;
data_contract = DataContract::from(system_contract);
println!("Processing SystemDataContract::DPNS {}", data_contract.identifier.to_string(Base58));
self.dao.create_data_contract(data_contract).await;
self.dao.create_data_contract(data_contract, owner, String::from("initChain")).await;

system_contract = SystemDataContract::Dashpay;
data_contract = DataContract::from(system_contract);
println!("Processing SystemDataContract::Dashpay {}", data_contract.identifier.to_string(Base58));
self.dao.create_data_contract(data_contract).await;
self.dao.create_data_contract(data_contract, owner, String::from("initChain")).await;
}
}

0 comments on commit 1025187

Please sign in to comment.