Added second keypair for encryption of domain names.

Changed keys file format to include second pair of keys, it will be in TOML now.
Made many adjustments to block and transaction structures.
Changed block serialization to binary format for hashing/mining.
Removed old build dependencies.
This commit is contained in:
Revertron
2021-05-04 16:47:03 +02:00
parent 52695e0988
commit bc6d2fbae3
19 changed files with 349 additions and 249 deletions
+4 -4
View File
@@ -16,16 +16,16 @@ pub struct Block {
pub difficulty: u32,
pub random: u32,
pub nonce: u64,
#[serde(skip_serializing_if = "Option::is_none")]
pub transaction: Option<Transaction>,
#[serde(default, skip_serializing_if = "Bytes::is_zero")]
pub prev_block_hash: Bytes,
#[serde(default, skip_serializing_if = "Bytes::is_zero")]
pub hash: Bytes,
#[serde(default, skip_serializing_if = "Bytes::is_zero")]
pub prev_block_hash: Bytes,
#[serde(default, skip_serializing_if = "Bytes::is_zero")]
pub pub_key: Bytes,
#[serde(default, skip_serializing_if = "Bytes::is_zero")]
pub signature: Bytes,
#[serde(skip_serializing_if = "Option::is_none")]
pub transaction: Option<Transaction>,
}
impl Block {
+17 -14
View File
@@ -17,7 +17,7 @@ use crate::blockchain::types::{BlockQuality, MineResult, Options, ZoneData};
use crate::blockchain::types::BlockQuality::*;
use crate::blockchain::types::MineResult::*;
use crate::commons::constants::*;
use crate::keys::check_public_key_strength;
use crate::keystore::check_public_key_strength;
use crate::settings::Settings;
const TEMP_DB_NAME: &str = ":memory:";
@@ -29,13 +29,13 @@ const SQL_GET_LAST_BLOCK: &str = "SELECT * FROM blocks ORDER BY id DESC LIMIT 1;
const SQL_TRUNCATE_BLOCKS: &str = "DELETE FROM blocks WHERE id >= ?;";
const SQL_TRUNCATE_DOMAINS: &str = "DELETE FROM domains WHERE id >= ?;";
const SQL_ADD_DOMAIN: &str = "INSERT INTO domains (id, timestamp, identity, confirmation, data, owner) VALUES (?, ?, ?, ?, ?, ?)";
const SQL_ADD_DOMAIN: &str = "INSERT INTO domains (id, timestamp, identity, confirmation, data, signing, encryption) VALUES (?, ?, ?, ?, ?, ?, ?)";
const SQL_GET_BLOCK_BY_ID: &str = "SELECT * FROM blocks WHERE id=? LIMIT 1;";
const SQL_GET_LAST_FULL_BLOCK: &str = "SELECT * FROM blocks WHERE id < ? AND `transaction`<>'' ORDER BY id DESC LIMIT 1;";
const SQL_GET_LAST_FULL_BLOCK_FOR_KEY: &str = "SELECT * FROM blocks WHERE id < ? AND `transaction`<>'' AND pub_key = ? ORDER BY id DESC LIMIT 1;";
const SQL_GET_DOMAIN_OWNER_BY_ID: &str = "SELECT owner FROM domains WHERE id < ? AND identity = ? LIMIT 1;";
const SQL_GET_DOMAIN_OWNER_BY_ID: &str = "SELECT signing FROM domains WHERE id < ? AND identity = ? LIMIT 1;";
const SQL_GET_DOMAIN_BY_ID: &str = "SELECT * FROM domains WHERE identity = ? ORDER BY id DESC LIMIT 1;";
const SQL_GET_DOMAINS_BY_KEY: &str = "SELECT * FROM domains WHERE owner = ?;";
const SQL_GET_DOMAINS_BY_KEY: &str = "SELECT * FROM domains WHERE signing = ?;";
const SQL_GET_OPTIONS: &str = "SELECT * FROM options;";
@@ -237,8 +237,8 @@ impl Chain {
let transaction = block.transaction.clone();
if self.add_block_to_table(block).is_ok() {
if let Some(mut transaction) = transaction {
if transaction.owner.is_empty() {
transaction.owner = owner;
if transaction.signing.is_empty() {
transaction.signing = owner;
}
self.add_transaction_to_table(index, timestamp, &transaction).expect("Error adding transaction");
}
@@ -374,7 +374,8 @@ impl Chain {
statement.bind(3, &**t.identity)?;
statement.bind(4, &**t.confirmation)?;
statement.bind(5, t.data.as_ref() as &str)?;
statement.bind(6, &**t.owner)?;
statement.bind(6, &**t.signing)?;
statement.bind(7, &**t.encryption)?;
statement.next()
}
@@ -534,7 +535,7 @@ impl Chain {
return WrongZone;
}
if let Some(transaction) = self.get_domain_transaction(&name) {
if transaction.owner.ne(pub_key) {
if transaction.signing.ne(pub_key) {
return NotOwned;
}
}
@@ -568,10 +569,11 @@ impl Chain {
}
let identity = Bytes::from_bytes(&statement.read::<Vec<u8>>(2).unwrap());
let confirmation = Bytes::from_bytes(&statement.read::<Vec<u8>>(3).unwrap());
let class = String::from("domain");
let class = String::from(CLASS_DOMAIN);
let data = statement.read::<String>(4).unwrap();
let pub_key = Bytes::from_bytes(&statement.read::<Vec<u8>>(5).unwrap());
let transaction = Transaction { identity, confirmation, class, data, owner: pub_key };
let signing = Bytes::from_bytes(&statement.read::<Vec<u8>>(5).unwrap());
let encryption = Bytes::from_bytes(&statement.read::<Vec<u8>>(6).unwrap());
let transaction = Transaction { identity, confirmation, class, data, signing, encryption };
debug!("Found transaction for domain {}: {:?}", domain, &transaction);
if transaction.check_identity(domain) {
return Some(transaction);
@@ -604,11 +606,12 @@ impl Chain {
let confirmation = Bytes::from_bytes(&statement.read::<Vec<u8>>(3).unwrap());
let class = String::from(CLASS_DOMAIN);
let data = statement.read::<String>(4).unwrap();
let owner = Bytes::from_bytes(&statement.read::<Vec<u8>>(5).unwrap());
let transaction = Transaction { identity: identity.clone(), confirmation: confirmation.clone(), class, data, owner };
let signing = Bytes::from_bytes(&statement.read::<Vec<u8>>(5).unwrap());
let encryption = Bytes::from_bytes(&statement.read::<Vec<u8>>(6).unwrap());
let transaction = Transaction { identity: identity.clone(), confirmation: confirmation.clone(), class, data, signing, encryption };
debug!("Found transaction for domain {:?}", &transaction);
if let Some(data) = transaction.get_domain_data() {
let decrypted = keystore.decrypt(data.domain.as_slice(), &confirmation.as_slice()[..12]);
let decrypted = keystore.decrypt(data.encrypted.as_slice());
let mut domain = String::from_utf8(decrypted.to_vec()).unwrap();
if domain.is_empty() {
domain = String::from("unknown");
+2 -1
View File
@@ -20,7 +20,8 @@ CREATE TABLE domains (
'identity' BINARY,
'confirmation' BINARY,
'data' TEXT,
'owner' BINARY
'signing' BINARY,
'encryption' BINARY
);
CREATE INDEX ids ON domains ('identity');
+19 -39
View File
@@ -1,8 +1,7 @@
use std::fmt;
use std::fmt::{Display, Formatter};
use serde::{Deserialize, Serialize, Serializer};
use serde::ser::SerializeStruct;
use serde::{Deserialize, Serialize};
use crate::blockchain::hash_utils::*;
use crate::bytes::Bytes;
@@ -12,7 +11,7 @@ use crate::{CLASS_ORIGIN, CLASS_DOMAIN};
extern crate serde;
extern crate serde_json;
#[derive(Clone, Deserialize, PartialEq)]
#[derive(Clone, Serialize, Deserialize, PartialEq)]
pub struct Transaction {
pub class: String,
#[serde(default, skip_serializing_if = "Bytes::is_zero")]
@@ -20,35 +19,27 @@ pub struct Transaction {
#[serde(default, skip_serializing_if = "Bytes::is_zero")]
pub confirmation: Bytes,
#[serde(default, skip_serializing_if = "Bytes::is_zero")]
pub owner: Bytes,
pub signing: Bytes,
#[serde(default, skip_serializing_if = "Bytes::is_zero")]
pub encryption: Bytes,
#[serde(default, skip_serializing_if = "String::is_empty")]
pub data: String,
}
impl Transaction {
pub fn from_str(identity: String, method: String, data: String, miner: Bytes, owner: Bytes) -> Self {
pub fn from_str(identity: String, method: String, data: String, signing: Bytes, encryption: Bytes) -> Self {
let hash = hash_identity(&identity, None);
let key = if owner.is_empty() {
&miner
} else {
&owner
};
let confirmation = hash_identity(&identity, Some(key));
// If the miner doesn't change owner, we don't include owner at all
let owner = if owner.is_empty() || owner == miner {
miner
} else {
owner
};
return Self::new(hash, confirmation, method, data, owner);
let confirmation = hash_identity(&identity, Some(&signing));
return Self::new(hash, confirmation, method, data, signing, encryption);
}
pub fn new(identity: Bytes, confirmation: Bytes, method: String, data: String, owner: Bytes) -> Self {
Transaction { identity, confirmation, class: method, data, owner }
pub fn new(identity: Bytes, confirmation: Bytes, method: String, data: String, signing: Bytes, encryption: Bytes) -> Self {
Transaction { identity, confirmation, class: method, data, signing, encryption }
}
pub fn origin(hash: Bytes, owner: Bytes) -> Self {
pub fn origin(hash: Bytes, signing: Bytes, encryption: Bytes) -> Self {
let data = serde_json::to_string(&Origin { zones: hash }).unwrap();
Transaction { identity: Bytes::default(), confirmation: Bytes::default(), class: String::from(CLASS_ORIGIN), data, owner }
Transaction { identity: Bytes::default(), confirmation: Bytes::default(), class: String::from(CLASS_ORIGIN), data, signing, encryption }
}
pub fn from_json(json: &str) -> Option<Self> {
@@ -70,7 +61,7 @@ impl Transaction {
pub fn check_identity(&self, domain: &str) -> bool {
let hash = hash_identity(&domain, None);
let confirmation = hash_identity(&domain, Some(&self.owner));
let confirmation = hash_identity(&domain, Some(&self.signing));
self.identity.eq(&hash) && self.confirmation.eq(&confirmation)
}
@@ -107,24 +98,13 @@ impl fmt::Debug for Transaction {
.field("class", &self.class)
.field("identity", &self.identity)
.field("confirmation", &self.confirmation)
.field("owner", &&self.owner)
.field("signing", &&self.signing)
.field("encryption", &&self.encryption)
.field("data", &self.data)
.finish()
}
}
impl Serialize for Transaction {
fn serialize<S>(&self, serializer: S) -> Result<<S as Serializer>::Ok, <S as Serializer>::Error> where S: Serializer {
let mut structure = serializer.serialize_struct("Transaction", 5).unwrap();
structure.serialize_field("class", &self.class)?;
structure.serialize_field("identity", &self.identity)?;
structure.serialize_field("confirmation", &self.confirmation)?;
structure.serialize_field("owner", &self.owner)?;
structure.serialize_field("data", &self.data)?;
structure.end()
}
}
pub enum TransactionType {
Unknown,
Signing,
@@ -134,7 +114,7 @@ pub enum TransactionType {
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct DomainData {
pub domain: Bytes,
pub encrypted: Bytes,
pub zone: String,
#[serde(default, skip_serializing_if = "String::is_empty")]
pub info: String,
@@ -145,8 +125,8 @@ pub struct DomainData {
}
impl DomainData {
pub fn new(domain: Bytes, zone: String, info: String, records: Vec<DnsRecord>, contacts: Vec<ContactsData>) -> Self {
Self { domain, zone, info, records, contacts }
pub fn new(encrypted: Bytes, zone: String, info: String, records: Vec<DnsRecord>, contacts: Vec<ContactsData>) -> Self {
Self { encrypted, zone, info, records, contacts }
}
}