Backporting to beta (#4118)
* Ignore get_price_info test by default. (#4112) * Auto-detect hex encoded bytes in sha3 (#4108) * Auto-detect hex encoded bytes in sha3 * Using types/isHex * Removing unused imports * Use binary chop to estimate gas accurately (#4100) * Initial sketch. * Building. * Fix a few things. * Fix issue, add tracing. * Address grumbles * Raise upper limit if needed * Fix test. * Fixing decoding API with signatures in names (#4125) * Fix call/estimate_gas (#4121) * Return 0 instead of error with out of gas on estimate_gas * Fix stuff up.
This commit is contained in:
parent
2b588d57f0
commit
5e70507c78
@ -873,6 +873,81 @@ impl BlockChainClient for Client {
|
||||
Ok(ret)
|
||||
}
|
||||
|
||||
fn estimate_gas(&self, t: &SignedTransaction, block: BlockId) -> Result<U256, CallError> {
|
||||
let header = self.block_header(block).ok_or(CallError::StatePruned)?;
|
||||
let last_hashes = self.build_last_hashes(header.parent_hash());
|
||||
let env_info = EnvInfo {
|
||||
number: header.number(),
|
||||
author: header.author(),
|
||||
timestamp: header.timestamp(),
|
||||
difficulty: header.difficulty(),
|
||||
last_hashes: last_hashes,
|
||||
gas_used: U256::zero(),
|
||||
gas_limit: U256::max_value(),
|
||||
};
|
||||
// that's just a copy of the state.
|
||||
let mut original_state = self.state_at(block).ok_or(CallError::StatePruned)?;
|
||||
let sender = t.sender().map_err(|e| {
|
||||
let message = format!("Transaction malformed: {:?}", e);
|
||||
ExecutionError::TransactionMalformed(message)
|
||||
})?;
|
||||
let balance = original_state.balance(&sender);
|
||||
let needed_balance = t.value + t.gas * t.gas_price;
|
||||
if balance < needed_balance {
|
||||
// give the sender a sufficient balance
|
||||
original_state.add_balance(&sender, &(needed_balance - balance), CleanupMode::NoEmpty);
|
||||
}
|
||||
let options = TransactOptions { tracing: true, vm_tracing: false, check_nonce: false };
|
||||
let mut tx = t.clone();
|
||||
|
||||
let mut cond = |gas| {
|
||||
let mut state = original_state.clone();
|
||||
tx.gas = gas;
|
||||
Executive::new(&mut state, &env_info, &*self.engine, &self.factories.vm)
|
||||
.transact(&tx, options.clone())
|
||||
.map(|r| r.trace[0].result.succeeded())
|
||||
.unwrap_or(false)
|
||||
};
|
||||
|
||||
let mut upper = env_info.gas_limit;
|
||||
if !cond(upper) {
|
||||
// impossible at block gas limit - try `UPPER_CEILING` instead.
|
||||
// TODO: consider raising limit by powers of two.
|
||||
const UPPER_CEILING: u64 = 1_000_000_000_000u64;
|
||||
upper = UPPER_CEILING.into();
|
||||
if !cond(upper) {
|
||||
trace!(target: "estimate_gas", "estimate_gas failed with {}", upper);
|
||||
return Err(CallError::Execution(ExecutionError::Internal))
|
||||
}
|
||||
}
|
||||
let lower = t.gas_required(&self.engine.schedule(&env_info)).into();
|
||||
if cond(lower) {
|
||||
trace!(target: "estimate_gas", "estimate_gas succeeded with {}", lower);
|
||||
return Ok(lower)
|
||||
}
|
||||
|
||||
/// Find transition point between `lower` and `upper` where `cond` changes from `false` to `true`.
|
||||
/// Returns the lowest value between `lower` and `upper` for which `cond` returns true.
|
||||
/// We assert: `cond(lower) = false`, `cond(upper) = true`
|
||||
fn binary_chop<F>(mut lower: U256, mut upper: U256, mut cond: F) -> U256 where F: FnMut(U256) -> bool {
|
||||
while upper - lower > 1.into() {
|
||||
let mid = (lower + upper) / 2.into();
|
||||
trace!(target: "estimate_gas", "{} .. {} .. {}", lower, mid, upper);
|
||||
let c = cond(mid);
|
||||
match c {
|
||||
true => upper = mid,
|
||||
false => lower = mid,
|
||||
};
|
||||
trace!(target: "estimate_gas", "{} => {} .. {}", c, lower, upper);
|
||||
}
|
||||
upper
|
||||
}
|
||||
|
||||
// binary chop to non-excepting call with gas somewhere between 21000 and block gas limit
|
||||
trace!(target: "estimate_gas", "estimate_gas chopping {} .. {}", lower, upper);
|
||||
Ok(binary_chop(lower, upper, cond))
|
||||
}
|
||||
|
||||
fn replay(&self, id: TransactionId, analytics: CallAnalytics) -> Result<Executed, CallError> {
|
||||
let address = self.transaction_address(id).ok_or(CallError::TransactionNotFound)?;
|
||||
let header = self.block_header(BlockId::Hash(address.block_hash)).ok_or(CallError::StatePruned)?;
|
||||
|
@ -379,6 +379,10 @@ impl BlockChainClient for TestBlockChainClient {
|
||||
self.execution_result.read().clone().unwrap()
|
||||
}
|
||||
|
||||
fn estimate_gas(&self, _t: &SignedTransaction, _block: BlockId) -> Result<U256, CallError> {
|
||||
Ok(21000.into())
|
||||
}
|
||||
|
||||
fn replay(&self, _id: TransactionId, _analytics: CallAnalytics) -> Result<Executed, CallError> {
|
||||
self.execution_result.read().clone().unwrap()
|
||||
}
|
||||
|
@ -184,6 +184,9 @@ pub trait BlockChainClient : Sync + Send {
|
||||
/// Makes a non-persistent transaction call.
|
||||
fn call(&self, t: &SignedTransaction, block: BlockId, analytics: CallAnalytics) -> Result<Executed, CallError>;
|
||||
|
||||
/// Estimates how much gas will be necessary for a call.
|
||||
fn estimate_gas(&self, t: &SignedTransaction, block: BlockId) -> Result<U256, CallError>;
|
||||
|
||||
/// Replays a given transaction for inspection.
|
||||
fn replay(&self, t: TransactionId, analytics: CallAnalytics) -> Result<Executed, CallError>;
|
||||
|
||||
|
@ -45,7 +45,7 @@ pub fn contract_address(address: &Address, nonce: &U256) -> Address {
|
||||
}
|
||||
|
||||
/// Transaction execution options.
|
||||
#[derive(Default)]
|
||||
#[derive(Default, Copy, Clone, PartialEq)]
|
||||
pub struct TransactOptions {
|
||||
/// Enable call tracing.
|
||||
pub tracing: bool,
|
||||
|
@ -673,7 +673,7 @@ impl MinerService for Miner {
|
||||
}
|
||||
}
|
||||
|
||||
fn call(&self, chain: &MiningBlockChainClient, t: &SignedTransaction, analytics: CallAnalytics) -> Result<Executed, CallError> {
|
||||
fn call(&self, client: &MiningBlockChainClient, t: &SignedTransaction, analytics: CallAnalytics) -> Result<Executed, CallError> {
|
||||
let sealing_work = self.sealing_work.lock();
|
||||
match sealing_work.queue.peek_last_ref() {
|
||||
Some(work) => {
|
||||
@ -681,7 +681,7 @@ impl MinerService for Miner {
|
||||
|
||||
// TODO: merge this code with client.rs's fn call somwhow.
|
||||
let header = block.header();
|
||||
let last_hashes = Arc::new(chain.last_hashes());
|
||||
let last_hashes = Arc::new(client.last_hashes());
|
||||
let env_info = EnvInfo {
|
||||
number: header.number(),
|
||||
author: *header.author(),
|
||||
@ -706,16 +706,14 @@ impl MinerService for Miner {
|
||||
state.add_balance(&sender, &(needed_balance - balance), CleanupMode::NoEmpty);
|
||||
}
|
||||
let options = TransactOptions { tracing: analytics.transaction_tracing, vm_tracing: analytics.vm_tracing, check_nonce: false };
|
||||
let mut ret = Executive::new(&mut state, &env_info, &*self.engine, chain.vm_factory()).transact(t, options)?;
|
||||
let mut ret = Executive::new(&mut state, &env_info, &*self.engine, client.vm_factory()).transact(t, options)?;
|
||||
|
||||
// TODO gav move this into Executive.
|
||||
ret.state_diff = original_state.map(|original| state.diff_from(original));
|
||||
|
||||
Ok(ret)
|
||||
},
|
||||
None => {
|
||||
chain.call(t, BlockId::Latest, analytics)
|
||||
}
|
||||
None => client.call(t, BlockId::Latest, analytics)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -82,7 +82,7 @@ impl PriceInfo {
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[test] #[ignore]
|
||||
fn should_get_price_info() {
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
|
@ -391,6 +391,14 @@ impl Res {
|
||||
Res::Call(_) | Res::FailedCall(_) | Res::FailedCreate(_) | Res::None => Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Did this call fail?
|
||||
pub fn succeeded(&self) -> bool {
|
||||
match *self {
|
||||
Res::Call(_) | Res::Create(_) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
@ -561,4 +569,3 @@ impl Decodable for VMTrace {
|
||||
Ok(res)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
//! Transaction data structure.
|
||||
|
||||
use std::ops::Deref;
|
||||
use std::ops::{Deref, DerefMut};
|
||||
use std::cell::*;
|
||||
use rlp::*;
|
||||
use util::sha3::Hashable;
|
||||
@ -239,6 +239,12 @@ impl Deref for SignedTransaction {
|
||||
}
|
||||
}
|
||||
|
||||
impl DerefMut for SignedTransaction {
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
&mut self.unsigned
|
||||
}
|
||||
}
|
||||
|
||||
impl Decodable for SignedTransaction {
|
||||
fn decode<D>(decoder: &D) -> Result<Self, DecoderError> where D: Decoder {
|
||||
let d = decoder.as_rlp();
|
||||
|
@ -23,12 +23,12 @@ import { eventSignature } from '../../util/signature';
|
||||
|
||||
export default class Event {
|
||||
constructor (abi) {
|
||||
this._name = abi.name;
|
||||
this._inputs = EventParam.toEventParams(abi.inputs || []);
|
||||
this._anonymous = !!abi.anonymous;
|
||||
|
||||
const { id, signature } = eventSignature(this._name, this.inputParamTypes());
|
||||
const { id, name, signature } = eventSignature(abi.name, this.inputParamTypes());
|
||||
this._id = id;
|
||||
this._name = name;
|
||||
this._signature = signature;
|
||||
}
|
||||
|
||||
|
@ -22,14 +22,14 @@ import { methodSignature } from '../util/signature';
|
||||
export default class Func {
|
||||
constructor (abi) {
|
||||
this._abi = abi;
|
||||
this._name = abi.name;
|
||||
this._constant = !!abi.constant;
|
||||
this._payable = abi.payable;
|
||||
this._inputs = Param.toParams(abi.inputs || []);
|
||||
this._outputs = Param.toParams(abi.outputs || []);
|
||||
|
||||
const { id, signature } = methodSignature(this._name, this.inputParamTypes());
|
||||
const { id, name, signature } = methodSignature(abi.name, this.inputParamTypes());
|
||||
this._id = id;
|
||||
this._name = name;
|
||||
this._signature = signature;
|
||||
}
|
||||
|
||||
|
@ -35,6 +35,18 @@ describe('abi/spec/Function', () => {
|
||||
});
|
||||
|
||||
describe('constructor', () => {
|
||||
it('returns signature correctly if name already contains it', () => {
|
||||
const func = new Func({
|
||||
name: 'test(bool,string)',
|
||||
inputs: inputsArr,
|
||||
outputs: outputsArr
|
||||
});
|
||||
|
||||
expect(func.name).to.equal('test');
|
||||
expect(func.id).to.equal('test(bool,string)');
|
||||
expect(func.signature).to.equal('02356205');
|
||||
});
|
||||
|
||||
it('stores the parameters as received', () => {
|
||||
expect(func.name).to.equal('test');
|
||||
expect(func.constant).to.be.false;
|
||||
|
@ -17,15 +17,31 @@
|
||||
import { keccak_256 } from 'js-sha3'; // eslint-disable-line camelcase
|
||||
import { fromParamType } from '../spec/paramType/format';
|
||||
|
||||
export function eventSignature (name, params) {
|
||||
export function eventSignature (eventName, params) {
|
||||
const { strName, name } = parseName(eventName);
|
||||
const types = (params || []).map(fromParamType).join(',');
|
||||
const id = `${name || ''}(${types})`;
|
||||
const id = `${strName}(${types})`;
|
||||
|
||||
return { id, signature: keccak_256(id) };
|
||||
return { id, name, signature: keccak_256(id) };
|
||||
}
|
||||
|
||||
export function methodSignature (name, params) {
|
||||
const { id, signature } = eventSignature(name, params);
|
||||
export function methodSignature (methodName, params) {
|
||||
const { id, name, signature } = eventSignature(methodName, params);
|
||||
|
||||
return { id, signature: signature.substr(0, 8) };
|
||||
return { id, name, signature: signature.substr(0, 8) };
|
||||
}
|
||||
|
||||
function parseName (name) {
|
||||
const strName = `${name || ''}`;
|
||||
const idx = strName.indexOf('(');
|
||||
|
||||
if (idx === -1) {
|
||||
return { strName, name };
|
||||
}
|
||||
|
||||
const trimmedName = strName.slice(0, idx);
|
||||
return {
|
||||
strName: trimmedName,
|
||||
name: trimmedName
|
||||
};
|
||||
}
|
||||
|
@ -19,50 +19,93 @@ import { eventSignature, methodSignature } from './signature';
|
||||
describe('abi/util/signature', () => {
|
||||
describe('eventSignature', () => {
|
||||
it('encodes signature baz() correctly', () => {
|
||||
expect(eventSignature('baz', []))
|
||||
.to.deep.equal({ id: 'baz()', signature: 'a7916fac4f538170f7cd12c148552e2cba9fcd72329a2dd5b07a6fa906488ddf' });
|
||||
expect(eventSignature('baz', [])).to.deep.equal({
|
||||
id: 'baz()',
|
||||
name: 'baz',
|
||||
signature: 'a7916fac4f538170f7cd12c148552e2cba9fcd72329a2dd5b07a6fa906488ddf'
|
||||
});
|
||||
});
|
||||
|
||||
it('encodes signature baz(uint32) correctly', () => {
|
||||
expect(eventSignature('baz', [{ type: 'uint', length: 32 }]))
|
||||
.to.deep.equal({ id: 'baz(uint32)', signature: '7d68785e8fc871be024b75964bd86d093511d4bc2dc7cf7bea32c48a0efaecb1' });
|
||||
expect(eventSignature('baz', [{ type: 'uint', length: 32 }])).to.deep.equal({
|
||||
id: 'baz(uint32)',
|
||||
name: 'baz',
|
||||
signature: '7d68785e8fc871be024b75964bd86d093511d4bc2dc7cf7bea32c48a0efaecb1'
|
||||
});
|
||||
});
|
||||
|
||||
it('encodes signature baz(uint32, bool) correctly', () => {
|
||||
expect(eventSignature('baz', [{ type: 'uint', length: 32 }, { type: 'bool' }]))
|
||||
.to.deep.equal({ id: 'baz(uint32,bool)', signature: 'cdcd77c0992ec5bbfc459984220f8c45084cc24d9b6efed1fae540db8de801d2' });
|
||||
expect(eventSignature('baz', [{ type: 'uint', length: 32 }, { type: 'bool' }])).to.deep.equal({
|
||||
id: 'baz(uint32,bool)',
|
||||
name: 'baz',
|
||||
signature: 'cdcd77c0992ec5bbfc459984220f8c45084cc24d9b6efed1fae540db8de801d2'
|
||||
});
|
||||
});
|
||||
|
||||
it('encodes no-name signature correctly as ()', () => {
|
||||
expect(eventSignature(undefined, []))
|
||||
.to.deep.equal({ id: '()', signature: '861731d50c3880a2ca1994d5ec287b94b2f4bd832a67d3e41c08177bdd5674fe' });
|
||||
expect(eventSignature(undefined, [])).to.deep.equal({
|
||||
id: '()',
|
||||
name: undefined,
|
||||
signature: '861731d50c3880a2ca1994d5ec287b94b2f4bd832a67d3e41c08177bdd5674fe'
|
||||
});
|
||||
});
|
||||
|
||||
it('encodes no-params signature correctly as ()', () => {
|
||||
expect(eventSignature(undefined, undefined))
|
||||
.to.deep.equal({ id: '()', signature: '861731d50c3880a2ca1994d5ec287b94b2f4bd832a67d3e41c08177bdd5674fe' });
|
||||
expect(eventSignature(undefined, undefined)).to.deep.equal({
|
||||
id: '()',
|
||||
name: undefined,
|
||||
signature: '861731d50c3880a2ca1994d5ec287b94b2f4bd832a67d3e41c08177bdd5674fe'
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('methodSignature', () => {
|
||||
it('encodes signature baz() correctly', () => {
|
||||
expect(methodSignature('baz', [])).to.deep.equal({ id: 'baz()', signature: 'a7916fac' });
|
||||
expect(methodSignature('baz', [])).to.deep.equal({
|
||||
id: 'baz()',
|
||||
name: 'baz',
|
||||
signature: 'a7916fac'
|
||||
});
|
||||
});
|
||||
|
||||
it('encodes signature baz(uint32) correctly', () => {
|
||||
expect(methodSignature('baz', [{ type: 'uint', length: 32 }])).to.deep.equal({ id: 'baz(uint32)', signature: '7d68785e' });
|
||||
expect(methodSignature('baz', [{ type: 'uint', length: 32 }])).to.deep.equal({
|
||||
id: 'baz(uint32)',
|
||||
name: 'baz',
|
||||
signature: '7d68785e'
|
||||
});
|
||||
});
|
||||
|
||||
it('encodes signature baz(uint32, bool) correctly', () => {
|
||||
expect(methodSignature('baz', [{ type: 'uint', length: 32 }, { type: 'bool' }])).to.deep.equal({ id: 'baz(uint32,bool)', signature: 'cdcd77c0' });
|
||||
expect(methodSignature('baz', [{ type: 'uint', length: 32 }, { type: 'bool' }])).to.deep.equal({
|
||||
id: 'baz(uint32,bool)',
|
||||
name: 'baz',
|
||||
signature: 'cdcd77c0'
|
||||
});
|
||||
});
|
||||
|
||||
it('encodes signature in name correctly', () => {
|
||||
expect(methodSignature('baz(uint32,bool)', [{ type: 'uint', length: 32 }, { type: 'bool' }])).to.deep.equal({
|
||||
id: 'baz(uint32,bool)',
|
||||
name: 'baz',
|
||||
signature: 'cdcd77c0'
|
||||
});
|
||||
});
|
||||
|
||||
it('encodes no-name signature correctly as ()', () => {
|
||||
expect(methodSignature(undefined, [])).to.deep.equal({ id: '()', signature: '861731d5' });
|
||||
expect(methodSignature(undefined, [])).to.deep.equal({
|
||||
id: '()',
|
||||
name: undefined,
|
||||
signature: '861731d5'
|
||||
});
|
||||
});
|
||||
|
||||
it('encodes no-params signature correctly as ()', () => {
|
||||
expect(methodSignature(undefined, undefined)).to.deep.equal({ id: '()', signature: '861731d5' });
|
||||
expect(methodSignature(undefined, undefined)).to.deep.equal({
|
||||
id: '()',
|
||||
name: undefined,
|
||||
signature: '861731d5'
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -17,9 +17,12 @@
|
||||
import { keccak_256 } from 'js-sha3'; // eslint-disable-line
|
||||
|
||||
import { hexToBytes } from './format';
|
||||
import { isHex } from './types';
|
||||
|
||||
export function sha3 (value, options) {
|
||||
if (options && options.encoding === 'hex') {
|
||||
const forceHex = options && options.encoding === 'hex';
|
||||
|
||||
if (forceHex || (!options && isHex(value))) {
|
||||
const bytes = hexToBytes(value);
|
||||
return sha3(bytes);
|
||||
}
|
||||
@ -28,3 +31,5 @@ export function sha3 (value, options) {
|
||||
|
||||
return `0x${hash}`;
|
||||
}
|
||||
|
||||
sha3.text = (val) => sha3(val, { encoding: 'raw' });
|
||||
|
@ -32,5 +32,14 @@ describe('api/util/sha3', () => {
|
||||
expect(sha3('01020304', { encoding: 'hex' })).to.equal('0xa6885b3731702da62e8e4a8f584ac46a7f6822f4e2ba50fba902f67b1588d23b');
|
||||
expect(sha3(Uint8Array.from([1, 2, 3, 4]))).to.equal('0xa6885b3731702da62e8e4a8f584ac46a7f6822f4e2ba50fba902f67b1588d23b');
|
||||
});
|
||||
|
||||
it('should interpret as bytes by default', () => {
|
||||
expect(sha3('0x01020304')).to.equal('0xa6885b3731702da62e8e4a8f584ac46a7f6822f4e2ba50fba902f67b1588d23b');
|
||||
});
|
||||
|
||||
it('should force text if option is passed', () => {
|
||||
expect(sha3('0x01020304', { encoding: 'raw' })).to.equal('0x16bff43de576d28857dcba65a56fc17c5e93c09bd6a709268eff8e62025ae869');
|
||||
expect(sha3.text('0x01020304')).to.equal('0x16bff43de576d28857dcba65a56fc17c5e93c09bd6a709268eff8e62025ae869');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -29,6 +29,10 @@ export function isFunction (test) {
|
||||
}
|
||||
|
||||
export function isHex (_test) {
|
||||
if (!isString(_test)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_test.substr(0, 2) === '0x') {
|
||||
return isHex(_test.slice(2));
|
||||
}
|
||||
|
@ -66,6 +66,12 @@ describe('api/util/types', () => {
|
||||
it('correctly identifies non-hex values', () => {
|
||||
expect(isHex('123j')).to.be.false;
|
||||
});
|
||||
|
||||
it('correctly indentifies non-string values', () => {
|
||||
expect(isHex(false)).to.be.false;
|
||||
expect(isHex()).to.be.false;
|
||||
expect(isHex([1, 2, 3])).to.be.false;
|
||||
});
|
||||
});
|
||||
|
||||
describe('isInstanceOf', () => {
|
||||
|
@ -91,7 +91,7 @@ export default class Registry {
|
||||
|
||||
lookupAddress (_name) {
|
||||
const name = _name.toLowerCase();
|
||||
const sha3 = this._api.util.sha3(name);
|
||||
const sha3 = this._api.util.sha3.text(name);
|
||||
|
||||
return this.getInstance().then((instance) => {
|
||||
return instance.getAddress.call({}, [sha3, 'A']);
|
||||
|
@ -39,7 +39,7 @@ export const lookup = (name, key) => (dispatch, getState) => {
|
||||
name = name.toLowerCase();
|
||||
dispatch(lookupStart(name, key));
|
||||
|
||||
getAddress.call({}, [ sha3(name), key ])
|
||||
getAddress.call({}, [ sha3.text(name), key ])
|
||||
.then((address) => dispatch(success('lookup', address)))
|
||||
.catch((err) => {
|
||||
console.error(`could not lookup ${key} for ${name}`);
|
||||
|
@ -62,7 +62,7 @@ export const reserve = (name) => (dispatch, getState) => {
|
||||
value: fee
|
||||
};
|
||||
const values = [
|
||||
sha3(name)
|
||||
sha3.text(name)
|
||||
];
|
||||
|
||||
return postTx(api, reserve, options, values);
|
||||
@ -116,7 +116,7 @@ export const drop = (name) => (dispatch, getState) => {
|
||||
};
|
||||
|
||||
const values = [
|
||||
sha3(name)
|
||||
sha3.text(name)
|
||||
];
|
||||
|
||||
return postTx(api, drop, options, values);
|
||||
|
@ -54,7 +54,7 @@ export const update = (name, key, value) => (dispatch, getState) => {
|
||||
};
|
||||
|
||||
const values = [
|
||||
sha3(name),
|
||||
sha3.text(name),
|
||||
key,
|
||||
value
|
||||
];
|
||||
|
@ -17,7 +17,7 @@
|
||||
export const getOwner = (contract, name) => {
|
||||
const { address, api } = contract;
|
||||
|
||||
const key = api.util.sha3(name) + '0000000000000000000000000000000000000000000000000000000000000001';
|
||||
const key = api.util.sha3.text(name) + '0000000000000000000000000000000000000000000000000000000000000001';
|
||||
const position = api.util.sha3(key, { encoding: 'hex' });
|
||||
|
||||
return api
|
||||
|
@ -68,13 +68,13 @@ const STORE = {
|
||||
};
|
||||
|
||||
function createApi (result = true) {
|
||||
const sha3 = sinon.stub().resolves('0x0000000000000000000000000000000000000000');
|
||||
sha3.text = sha3;
|
||||
return {
|
||||
parity: {
|
||||
registryAddress: sinon.stub().resolves('0x0000000000000000000000000000000000000000')
|
||||
},
|
||||
util: {
|
||||
sha3: sinon.stub().resolves('0x0000000000000000000000000000000000000000')
|
||||
}
|
||||
util: { sha3 }
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -59,7 +59,7 @@ export default class EmailVerificationStore extends VerificationStore {
|
||||
super(api, EmailVerificationABI, EMAIL_VERIFICATION, account, isTestnet);
|
||||
}
|
||||
|
||||
requestValues = () => [ sha3(this.email) ]
|
||||
requestValues = () => [ sha3.text(this.email) ]
|
||||
|
||||
@action setEmail = (email) => {
|
||||
this.email = email;
|
||||
|
@ -120,7 +120,7 @@ export default class VerificationStore {
|
||||
|
||||
const confirm = contract.functions.find((fn) => fn.name === 'confirm');
|
||||
const options = { from: account };
|
||||
const values = [ sha3(code) ];
|
||||
const values = [ sha3.text(code) ];
|
||||
|
||||
this.code = code;
|
||||
this.isCodeValid = null;
|
||||
@ -192,7 +192,7 @@ export default class VerificationStore {
|
||||
|
||||
@action sendConfirmation = () => {
|
||||
const { api, account, contract, code } = this;
|
||||
const token = sha3(code);
|
||||
const token = sha3.text(code);
|
||||
|
||||
const confirm = contract.functions.find((fn) => fn.name === 'confirm');
|
||||
const options = { from: account };
|
||||
|
@ -85,7 +85,7 @@ export default class AddressSelectStore {
|
||||
return emailVerification
|
||||
.instance
|
||||
.reverse
|
||||
.call({}, [ sha3(email) ])
|
||||
.call({}, [ sha3.text(email) ])
|
||||
.then((address) => {
|
||||
return {
|
||||
address,
|
||||
@ -109,7 +109,7 @@ export default class AddressSelectStore {
|
||||
this.regLookups.push((name) => {
|
||||
return registryInstance
|
||||
.getAddress
|
||||
.call({}, [ sha3(name), 'A' ])
|
||||
.call({}, [ sha3.text(name), 'A' ])
|
||||
.then((address) => {
|
||||
return {
|
||||
address,
|
||||
|
@ -141,7 +141,7 @@ class Background extends Component {
|
||||
generateSeed () {
|
||||
const { api, muiTheme } = this.context;
|
||||
|
||||
return api.util.sha3(`${muiTheme.backgroundSeed}${Math.random()}${counter++}`);
|
||||
return api.util.sha3.text(`${muiTheme.backgroundSeed}${Math.random()}${counter++}`);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -671,13 +671,8 @@ impl<C, SN: ?Sized, S: ?Sized, M, EM> Eth for EthClient<C, SN, S, M, EM> where
|
||||
|
||||
let request = CallRequest::into(request);
|
||||
let signed = self.sign_call(request)?;
|
||||
let result = match num.0 {
|
||||
BlockNumber::Pending => take_weak!(self.miner).call(&*take_weak!(self.client), &signed, Default::default()),
|
||||
num => take_weak!(self.client).call(&signed, num.into(), Default::default()),
|
||||
};
|
||||
|
||||
result
|
||||
.map(|res| (res.gas_used + res.refunded).into())
|
||||
take_weak!(self.client).estimate_gas(&signed, num.0.into())
|
||||
.map(Into::into)
|
||||
.map_err(errors::from_call_error)
|
||||
}
|
||||
|
||||
|
@ -691,7 +691,7 @@ fn rpc_eth_estimate_gas() {
|
||||
"latest"],
|
||||
"id": 1
|
||||
}"#;
|
||||
let response = r#"{"jsonrpc":"2.0","result":"0xff35","id":1}"#;
|
||||
let response = r#"{"jsonrpc":"2.0","result":"0x5208","id":1}"#;
|
||||
|
||||
assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned()));
|
||||
}
|
||||
@ -725,7 +725,7 @@ fn rpc_eth_estimate_gas_default_block() {
|
||||
}],
|
||||
"id": 1
|
||||
}"#;
|
||||
let response = r#"{"jsonrpc":"2.0","result":"0xff35","id":1}"#;
|
||||
let response = r#"{"jsonrpc":"2.0","result":"0x5208","id":1}"#;
|
||||
|
||||
assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned()));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user