Skip to content

Commit

Permalink
Merge pull request #76 from dfinance/bech32-in-genesis
Browse files Browse the repository at this point in the history
Bech32 in genesis
  • Loading branch information
mkurnikov authored May 29, 2020
2 parents aadda00 + 9ff3596 commit e5fcab0
Show file tree
Hide file tree
Showing 8 changed files with 179 additions and 50 deletions.
2 changes: 1 addition & 1 deletion crates/dialects/lang/src/dfina/data_cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ impl<'txn> DataCache<'txn> {
pub fn resource_changes(self) -> VMResult<Vec<ResourceChange>> {
let mut resources = vec![];
for (ap, change) in self.inner.data_map {
let account_address = format!("0x{}", ap.address);
let account_address = format!("0x{}", ap.address.to_string().trim_start_matches('0'));
match change {
None => {
let ty = self
Expand Down
33 changes: 22 additions & 11 deletions crates/dialects/lang/src/dfina/resources.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,10 @@ impl Into<ResourceType> for ResourceStructType {
}
}

pub fn resource_into_access_path(ty: ResourceType) -> Result<AccessPath> {
pub fn resource_into_access_path(
account_address: AccountAddress,
ty: ResourceType,
) -> Result<AccessPath> {
let mut ty_args = Vec::with_capacity(ty.ty_args.len());
for ty_arg_s in ty.ty_args {
let quoted = format!(r#""{}""#, ty_arg_s);
Expand All @@ -72,7 +75,7 @@ pub fn resource_into_access_path(ty: ResourceType) -> Result<AccessPath> {
layout,
};
let struct_tag = struct_type.struct_tag()?;
let resource_key = ResourceKey::new(struct_type.address, struct_tag);
let resource_key = ResourceKey::new(account_address, struct_tag);
Ok(AccessPath::resource_access_path(&resource_key))
}

Expand All @@ -96,15 +99,23 @@ pub fn into_write_op(op: ResourceChangeOp) -> WriteOp {

pub fn changes_into_writeset(changes: Vec<ResourceChange>) -> Result<WriteSet> {
let mut write_set = WriteSetMut::default();
for change in changes {
let access_path = resource_into_access_path(change.ty.clone()).with_context(|| {
format!(
"Resource {} does not correspond to any valid struct in the chain",
&change.ty
)
})?;
let op = into_write_op(change.op);
write_set.push((access_path, op));
for ResourceChange {
account: account_address,
ty: resource_type,
op: change_op,
} in changes
{
// account_address here is already in Libra 0x format and validated, even for dfinance case
let account_address = AccountAddress::from_hex_literal(&account_address)?;
let access_path = resource_into_access_path(account_address, resource_type.clone())
.with_context(|| {
format!(
"Cannot form a valid resource AccessPath from a string {:?}",
&resource_type.to_string()
)
})?;
let write_op = into_write_op(change_op);
write_set.push((access_path, write_op));
}
Ok(write_set
.freeze()
Expand Down
2 changes: 1 addition & 1 deletion crates/dialects/lang/src/libra/data_cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ impl<'txn> DataCache<'txn> {
pub fn resource_changes(self) -> VMResult<Vec<ResourceChange>> {
let mut resources = vec![];
for (ap, change) in self.inner.data_map {
let account_address = format!("0x{}", ap.address);
let account_address = format!("0x{}", ap.address.to_string().trim_start_matches('0'));
match change {
None => {
let ty = self
Expand Down
33 changes: 22 additions & 11 deletions crates/dialects/lang/src/libra/resources.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,10 @@ impl Into<ResourceType> for ResourceStructType {
}
}

pub fn resource_into_access_path(ty: ResourceType) -> Result<AccessPath> {
pub fn resource_into_access_path(
account_address: AccountAddress,
ty: ResourceType,
) -> Result<AccessPath> {
let mut ty_args = Vec::with_capacity(ty.ty_args.len());
for ty_arg_s in ty.ty_args {
let quoted = format!(r#""{}""#, ty_arg_s);
Expand All @@ -72,7 +75,7 @@ pub fn resource_into_access_path(ty: ResourceType) -> Result<AccessPath> {
layout,
};
let struct_tag = struct_type.struct_tag()?;
let resource_key = ResourceKey::new(struct_type.address, struct_tag);
let resource_key = ResourceKey::new(account_address, struct_tag);
Ok(AccessPath::resource_access_path(&resource_key))
}

Expand All @@ -96,15 +99,23 @@ pub fn into_write_op(op: ResourceChangeOp) -> WriteOp {

pub fn changes_into_writeset(changes: Vec<ResourceChange>) -> Result<WriteSet> {
let mut write_set = WriteSetMut::default();
for change in changes {
let access_path = resource_into_access_path(change.ty.clone()).with_context(|| {
format!(
"Resource {} does not correspond to any valid struct in the chain",
&change.ty
)
})?;
let op = into_write_op(change.op);
write_set.push((access_path, op));
for ResourceChange {
account: account_address,
ty: resource_type,
op: change_op,
} in changes
{
// account_address here is already in Libra 0x format and validated, even for dfinance case
let account_address = AccountAddress::from_hex_literal(&account_address)?;
let access_path = resource_into_access_path(account_address, resource_type.clone())
.with_context(|| {
format!(
"Cannot form a valid resource AccessPath from a string {:?}",
&resource_type.to_string()
)
})?;
let write_op = into_write_op(change_op);
write_set.push((access_path, write_op));
}
Ok(write_set
.freeze()
Expand Down
21 changes: 18 additions & 3 deletions crates/dialects/shared/src/results.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use core::fmt;
use serde::export::Formatter;
use std::fmt::Display;
use std::fmt::{Debug, Display};

#[derive(Debug, serde::Serialize, serde::Deserialize)]
#[serde(tag = "type")]
Expand Down Expand Up @@ -45,7 +45,7 @@ impl ResourceChange {
}
}

#[derive(Debug, serde::Serialize)]
#[derive(serde::Serialize)]
pub struct ExecutionError {
/// String representation of StatusCode enum.
pub status: String,
Expand All @@ -57,11 +57,26 @@ pub struct ExecutionError {
pub message: Option<String>,
}

impl Debug for ExecutionError {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
let mut formatted_struct = f.debug_struct("ExecutionError");
formatted_struct.field("status", &self.status);

if let Some(sub_status) = self.sub_status {
formatted_struct.field("sub_status", &sub_status);
}
if let Some(message) = &self.message {
formatted_struct.field("message", &message);
}
formatted_struct.finish()
}
}

pub type ExecResult<T> = Result<T, ExecutionError>;

impl Display for ExecutionError {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
write!(f, "{:?}", self)
f.write_str(&format!("{:#?}", self))
}
}

Expand Down
5 changes: 3 additions & 2 deletions crates/dialects/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ impl Dialect for MoveDialect {
args: Vec<String>,
) -> Result<Vec<ResourceChange>> {
let genesis_write_set = libra::resources::changes_into_writeset(genesis_changes)
.context("Invalid genesis")?;
.with_context(|| "Provided genesis serialization error")?;
libra::executor::compile_and_run(script, deps, raw_sender_string, genesis_write_set, args)
}

Expand Down Expand Up @@ -151,7 +151,8 @@ impl Dialect for DFinanceDialect {
genesis_changes: Vec<ResourceChange>,
args: Vec<String>,
) -> Result<Vec<ResourceChange>> {
let genesis_write_set = dfina::resources::changes_into_writeset(genesis_changes)?;
let genesis_write_set = dfina::resources::changes_into_writeset(genesis_changes)
.with_context(|| "Provided genesis serialization error")?;
dfina::executor::compile_and_run(script, deps, raw_sender_string, genesis_write_set, args)
}

Expand Down
73 changes: 61 additions & 12 deletions crates/integration_tests/tests/test_executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ script {
assert_eq!(
changes,
serde_json::json!([{
"account": "0x00000000000000001111111111111111",
"account": "0x1111111111111111",
"ty": {
"address": "0x00000000000000001111111111111111",
"module": "Record",
Expand All @@ -151,7 +151,7 @@ script {
let deps = vec![stdlib_transaction_mod(), record_mod()];

let initial_chain_state = serde_json::json!([{
"account": "0x00000000000000001111111111111111",
"account": "0x1111111111111111",
"ty": {
"address": "0x00000000000000001111111111111111",
"module": "Record",
Expand All @@ -173,7 +173,7 @@ script {
assert_eq!(
changes,
serde_json::json!([{
"account": "0x00000000000000001111111111111111",
"account": "0x1111111111111111",
"ty": {
"address": "0x00000000000000001111111111111111",
"module": "Record",
Expand Down Expand Up @@ -225,7 +225,7 @@ script {
serde_json::to_value(changes).unwrap(),
serde_json::json!([
{
"account": "0x00000000000000000000000000000001",
"account": "0x1",
"ty": {
"address": "0x00000000000000000000000000000001",
"module": "M",
Expand Down Expand Up @@ -278,9 +278,9 @@ script {
changes,
serde_json::json!([
{
"account": "0xde5f86ce8ad7944f272d693cb4625a955b610150",
"account": "wallet1me0cdn52672y7feddy7tgcj6j4dkzq2su745vh",
"ty": {
"address": "0xde5f86ce8ad7944f272d693cb4625a955b610150",
"address": "wallet1me0cdn52672y7feddy7tgcj6j4dkzq2su745vh",
"module": "M",
"name": "T",
"ty_args": [],
Expand Down Expand Up @@ -333,7 +333,7 @@ script {
changes,
serde_json::json!([
{
"account": "0x00000000000000000000000000000001",
"account": "0x1",
"ty": {
"address": "0x00000000000000000000000000000001",
"module": "Module",
Expand Down Expand Up @@ -397,7 +397,7 @@ script {
let initial_chain_state = serde_json::json!([{
"account": "0x1111111111111111",
"ty": {
"address": "0x1111111111111111",
"address": "0x00000000000000001111111111111111",
"module": "Record",
"name": "T",
"ty_args": [],
Expand All @@ -417,7 +417,7 @@ script {
assert_eq!(
changes,
serde_json::json!([{
"account": "0x00000000000000001111111111111111",
"account": "0x1111111111111111",
"ty": {
"address": "0x00000000000000001111111111111111",
"module": "Record",
Expand All @@ -444,7 +444,7 @@ script {
let deps = vec![stdlib_transaction_mod(), record_mod()];

let initial_chain_state = serde_json::json!([{
"account": "0x00000000000000001111111111111111",
"account": "0x1111111111111111",
"ty": {
"address": "0x00000000000000001111111111111111",
"module": "Record",
Expand All @@ -468,7 +468,7 @@ script {
changes,
serde_json::json!([
{
"account": "0x00000000000000001111111111111111",
"account": "0x1111111111111111",
"ty": {
"address": "0x00000000000000001111111111111111",
"module": "Record",
Expand All @@ -479,7 +479,7 @@ script {
"op": {"type": "Delete"},
},
{
"account": "0x00000000000000002222222222222222",
"account": "0x2222222222222222",
"ty": {
"address": "0x00000000000000001111111111111111",
"module": "Record",
Expand Down Expand Up @@ -521,3 +521,52 @@ script {
"Unbound module \'wallet1pxqfjvnu0utauj8fctw2s7j4mfyvrsjd59c2u8::Unknown\'"
);
}

#[test]
fn test_bech32_in_genesis_json() {
let script_text = r"
script {
use 0x1111111111111111::Record;
fun main() {
let record = Record::with_doubled_age();
Record::save(record);
}
}";
let deps = vec![stdlib_transaction_mod(), record_mod()];
let initial_chain_state = serde_json::json!([{
"account": "wallet1pxqfjvnu0utauj8fctw2s7j4mfyvrsjd59c2u8",
"ty": {
"address": "0x0000000000000000000000001111111111111111",
"module": "Record",
"name": "T",
"ty_args": [],
"layout": ["U8"]
},
"op": {"type": "SetValue", "values": [10]}
}]);

let changes = compile_and_execute_script(
(get_script_path(), script_text.to_string()),
&deps,
"dfinance",
"wallet1pxqfjvnu0utauj8fctw2s7j4mfyvrsjd59c2u8",
initial_chain_state,
vec![],
)
.unwrap();
assert_eq!(
changes,
serde_json::json!([{
"account": "wallet1pxqfjvnu0utauj8fctw2s7j4mfyvrsjd59c2u8",
"ty": {
"address": "0x0000000000000000000000001111111111111111",
"module": "Record",
"name": "T",
"ty_args": [],
"layout": ["U8"]
},
"op": {"type": "SetValue", "values": [20]}
}])
);
}
Loading

0 comments on commit e5fcab0

Please sign in to comment.