Skip to content

Commit

Permalink
output hex strings with 0x prefix, output account balance as hex stri…
Browse files Browse the repository at this point in the history
…ng, be permissive with inputted hex strings
  • Loading branch information
kantai committed Apr 6, 2020
1 parent 297de0c commit 8fa73b4
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 30 deletions.
21 changes: 11 additions & 10 deletions docs/rpc-endpoints.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,16 @@ Returns JSON data in the form:

```
{
"balance": 100,
"balance": "0x100..",
"nonce": 1,
"balanceProof": "01fa...",
"nonceProof": "01ab...",
"balanceProof": "0x01fa...",
"nonceProof": "0x01ab...",
}
```

Where balance (a u128) and nonce (a u64) are both integers, and the proofs are provided as
hex strings.
Where balance is the hex encoding of a unsigned 128-bit integer
(big-endian), nonce is a unsigned 64-bit integer, and the proofs are
provided as hex strings.

For non-existent accounts, this _does not_ 404, rather it returns an
object with balance and nonce of 0.
Expand All @@ -44,8 +45,8 @@ Returns JSON data in the form:

```
{
"data": "01ce...",
"proof": "01ab...",
"data": "0x01ce...",
"proof": "0x01ab...",
}
```

Expand Down Expand Up @@ -220,7 +221,7 @@ published in, and the MARF proof for the data.
{
"source": "(define-private ...",
"publishHeight": 1,
"proof": "00213..."
"proof": "0x00213..."
}
```

Expand All @@ -238,7 +239,7 @@ the simulated `tx-sender` are supplied via the POST body in the following JSON f
```
{
"sender": "SP31DA6FTSJX2WGTZ69SFY11BH51NZMB0ZW97B5P0.get-info",
"arguments": [ "0011...", "00231..." ]
"arguments": [ "0x0011...", "0x00231..." ]
}
```

Expand All @@ -250,7 +251,7 @@ This endpoint returns a JSON object of the following form:
```
{
"okay": true,
"result": "0011..."
"result": "0x0011..."
}
```

Expand Down
2 changes: 1 addition & 1 deletion src/net/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -858,7 +858,7 @@ pub struct CallReadOnlyResponse {

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct AccountEntryResponse {
pub balance: u128,
pub balance: String,
pub nonce: u64,
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(default)]
Expand Down
13 changes: 7 additions & 6 deletions src/net/rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -374,8 +374,8 @@ impl ConversationHttp {
let data = chainstate.with_read_only_clarity_tx(cur_burn, cur_block, |clarity_tx| {
clarity_tx.with_clarity_db_readonly(|clarity_db| {
let key = ClarityDatabase::make_key_for_account_balance(&account);
let (balance, balance_proof) = clarity_db.get_with_proof(&key)
.map(|(a, b)| (a, b.to_hex()))
let (balance, balance_proof) = clarity_db.get_with_proof::<u128>(&key)
.map(|(a, b)| (a, format!("0x{}", b.to_hex())))
.unwrap_or_else(|| (0, "".into()));
let balance_proof = if with_proof {
Some(balance_proof)
Expand All @@ -384,14 +384,15 @@ impl ConversationHttp {
};
let key = ClarityDatabase::make_key_for_account_nonce(&account);
let (nonce, nonce_proof) = clarity_db.get_with_proof(&key)
.map(|(a, b)| (a, b.to_hex()))
.map(|(a, b)| (a, format!("0x{}", b.to_hex())))
.unwrap_or_else(|| (0, "".into()));
let nonce_proof = if with_proof {
Some(nonce_proof)
} else {
None
};

let balance = format!("0x{}", to_hex(&balance.to_be_bytes()));
AccountEntryResponse { balance, nonce, balance_proof, nonce_proof }
})
});
Expand All @@ -413,15 +414,15 @@ impl ConversationHttp {
clarity_tx.with_clarity_db_readonly(|clarity_db| {
let key = ClarityDatabase::make_key_for_data_map_entry(&contract_identifier, map_name, key);
let (value, marf_proof) = clarity_db.get_with_proof::<Value>(&key)
.map(|(a, b)| (a, b.to_hex()))
.map(|(a, b)| (a, format!("0x{}", b.to_hex())))
.unwrap_or_else(|| (Value::none(), "".into()));
let marf_proof = if with_proof {
Some(marf_proof)
} else {
None
};

let data = value.serialize();
let data = format!("0x{}", value.serialize());
MapEntryResponse { data, marf_proof }
})
});
Expand Down Expand Up @@ -452,7 +453,7 @@ impl ConversationHttp {

let response = match data {
Ok(data) =>
CallReadOnlyResponse { okay: true, result: Some(data.serialize()), cause: None },
CallReadOnlyResponse { okay: true, result: Some(format!("0x{}", data.serialize())), cause: None },
Err(e) =>
CallReadOnlyResponse { okay: false, result: None, cause: Some(e.to_string()) },
};
Expand Down
24 changes: 11 additions & 13 deletions src/vm/tests/integrations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -187,8 +187,6 @@ fn integration_test_get_info() {

conf.burnchain.block_time = 1500;

let contract_sk = StacksPrivateKey::new();

let num_rounds = 4;

let mut run_loop = testnet::helium::RunLoop::new(conf);
Expand Down Expand Up @@ -356,7 +354,7 @@ fn integration_test_get_info() {
.json(&key.serialize())
.send()
.unwrap().json::<HashMap<String, String>>().unwrap();
let result_data = Value::try_deserialize_hex_untyped(&res["data"]).unwrap();
let result_data = Value::try_deserialize_hex_untyped(&res["data"][2..]).unwrap();
let expected_data = chain_state.clarity_eval_read_only(bhh, &contract_identifier,
"(some (get-exotic-data-info u1))");
assert!(res.get("proof").is_some());
Expand All @@ -371,7 +369,7 @@ fn integration_test_get_info() {
.json(&key.serialize())
.send()
.unwrap().json::<HashMap<String, String>>().unwrap();
let result_data = Value::try_deserialize_hex_untyped(&res["data"]).unwrap();
let result_data = Value::try_deserialize_hex_untyped(&res["data"][2..]).unwrap();
assert_eq!(result_data, Value::none());

let sender_addr = to_addr(&StacksPrivateKey::from_hex(SK_3).unwrap());
Expand All @@ -390,7 +388,7 @@ fn integration_test_get_info() {
.unwrap().json::<HashMap<String, String>>().unwrap();

assert!(res.get("proof").is_none());
let result_data = Value::try_deserialize_hex_untyped(&res["data"]).unwrap();
let result_data = Value::try_deserialize_hex_untyped(&res["data"][2..]).unwrap();
let expected_data = chain_state.clarity_eval_read_only(bhh, &contract_identifier,
"(some (get-exotic-data-info u1))");
eprintln!("{}", serde_json::to_string(&res).unwrap());
Expand All @@ -411,7 +409,7 @@ fn integration_test_get_info() {
.unwrap().json::<HashMap<String, String>>().unwrap();

assert!(res.get("proof").is_some());
let result_data = Value::try_deserialize_hex_untyped(&res["data"]).unwrap();
let result_data = Value::try_deserialize_hex_untyped(&res["data"][2..]).unwrap();
let expected_data = chain_state.clarity_eval_read_only(bhh, &contract_identifier,
"(some (get-exotic-data-info u1))");
eprintln!("{}", serde_json::to_string(&res).unwrap());
Expand All @@ -423,7 +421,7 @@ fn integration_test_get_info() {
&http_origin, &sender_addr);
eprintln!("Test: GET {}", path);
let res = client.get(&path).send().unwrap().json::<AccountEntryResponse>().unwrap();
assert_eq!(res.balance, 100000);
assert_eq!(u128::from_str_radix(&res.balance[2..], 16).unwrap(), 100000);
assert_eq!(res.nonce, 3);
assert!(res.nonce_proof.is_some());
assert!(res.balance_proof.is_some());
Expand All @@ -433,7 +431,7 @@ fn integration_test_get_info() {
&http_origin, &contract_addr);
eprintln!("Test: GET {}", path);
let res = client.get(&path).send().unwrap().json::<AccountEntryResponse>().unwrap();
assert_eq!(res.balance, 0);
assert_eq!(u128::from_str_radix(&res.balance[2..], 16).unwrap(), 0);
assert_eq!(res.nonce, 1);
assert!(res.nonce_proof.is_some());
assert!(res.balance_proof.is_some());
Expand All @@ -443,7 +441,7 @@ fn integration_test_get_info() {
&http_origin, ADDR_4);
eprintln!("Test: GET {}", path);
let res = client.get(&path).send().unwrap().json::<AccountEntryResponse>().unwrap();
assert_eq!(res.balance, 300);
assert_eq!(u128::from_str_radix(&res.balance[2..], 16).unwrap(), 300);
assert_eq!(res.nonce, 0);
assert!(res.nonce_proof.is_some());
assert!(res.balance_proof.is_some());
Expand All @@ -453,7 +451,7 @@ fn integration_test_get_info() {
&http_origin, &contract_addr);
eprintln!("Test: GET {}", path);
let res = client.get(&path).send().unwrap().json::<AccountEntryResponse>().unwrap();
assert_eq!(res.balance, 0);
assert_eq!(u128::from_str_radix(&res.balance[2..], 16).unwrap(), 0);
assert_eq!(res.nonce, 0);
assert!(res.nonce_proof.is_some());
assert!(res.balance_proof.is_some());
Expand All @@ -462,7 +460,7 @@ fn integration_test_get_info() {
&http_origin, ADDR_4);
eprintln!("Test: GET {}", path);
let res = client.get(&path).send().unwrap().json::<AccountEntryResponse>().unwrap();
assert_eq!(res.balance, 300);
assert_eq!(u128::from_str_radix(&res.balance[2..], 16).unwrap(), 300);
assert_eq!(res.nonce, 0);
assert!(res.nonce_proof.is_none());
assert!(res.balance_proof.is_none());
Expand All @@ -471,7 +469,7 @@ fn integration_test_get_info() {
&http_origin, ADDR_4);
eprintln!("Test: GET {}", path);
let res = client.get(&path).send().unwrap().json::<AccountEntryResponse>().unwrap();
assert_eq!(res.balance, 300);
assert_eq!(u128::from_str_radix(&res.balance[2..], 16).unwrap(), 300);
assert_eq!(res.nonce, 0);
assert!(res.nonce_proof.is_some());
assert!(res.balance_proof.is_some());
Expand Down Expand Up @@ -543,7 +541,7 @@ fn integration_test_get_info() {
assert!(res.get("cause").is_none());
assert!(res["okay"].as_bool().unwrap());

let result_data = Value::try_deserialize_hex_untyped(res["result"].as_str().unwrap()).unwrap();
let result_data = Value::try_deserialize_hex_untyped(&res["result"].as_str().unwrap()[2..]).unwrap();
let expected_data = chain_state.clarity_eval_read_only(bhh, &contract_identifier,
"(get-exotic-data-info u1)");
assert_eq!(result_data, expected_data);
Expand Down
8 changes: 8 additions & 0 deletions src/vm/types/serialization.rs
Original file line number Diff line number Diff line change
Expand Up @@ -475,6 +475,11 @@ impl Value {
}

pub fn try_deserialize_hex_untyped(hex: &str) -> Result<Value, SerializationError> {
let hex = if hex.starts_with("0x") {
&hex[2..]
} else {
&hex
};
let mut data = hex_bytes(hex)
.map_err(|_| "Bad hex string")?;
Value::try_deserialize_bytes_untyped(&mut data)
Expand Down Expand Up @@ -765,6 +770,9 @@ mod tests {
assert_eq!(
expected,
&Value::try_deserialize_hex_untyped(test));
assert_eq!(
expected,
&Value::try_deserialize_hex_untyped(&format!("0x{}", test)));
}
}

Expand Down

0 comments on commit 8fa73b4

Please sign in to comment.