From 2505b8ed9007a9c4c1423d3ad460d7ed8f81b8ef Mon Sep 17 00:00:00 2001 From: chriseth Date: Mon, 16 Mar 2015 16:15:13 +0100 Subject: [PATCH 01/66] Provide access to storage offsets via contract type. --- libsolidity/Compiler.cpp | 17 +++-------------- libsolidity/Types.cpp | 26 +++++++++++++++++++++++--- libsolidity/Types.h | 4 ++++ 3 files changed, 30 insertions(+), 17 deletions(-) diff --git a/libsolidity/Compiler.cpp b/libsolidity/Compiler.cpp index db61cc4a1..8e2634499 100644 --- a/libsolidity/Compiler.cpp +++ b/libsolidity/Compiler.cpp @@ -20,12 +20,12 @@ * Solidity compiler. */ +#include #include #include #include #include #include -#include #include #include @@ -274,19 +274,8 @@ void Compiler::appendReturnValuePacker(TypePointers const& _typeParameters) void Compiler::registerStateVariables(ContractDefinition const& _contract) { - vector variables; - for (ContractDefinition const* contract: boost::adaptors::reverse(_contract.getLinearizedBaseContracts())) - for (ASTPointer const& variable: contract->getStateVariables()) - if (!variable->isConstant()) - variables.push_back(variable.get()); - TypePointers types; - for (auto variable: variables) - types.push_back(variable->getType()); - StorageOffsets offsets; - offsets.computeOffsets(types); - for (size_t index = 0; index < variables.size(); ++index) - if (auto const* offset = offsets.getOffset(index)) - m_context.addStateVariable(*variables[index], offset->first, offset->second); + for (auto const& var: ContractType(_contract).getStateVariables()) + m_context.addStateVariable(*get<0>(var), get<1>(var), get<2>(var)); } void Compiler::initializeStateVariables(ContractDefinition const& _contract) diff --git a/libsolidity/Types.cpp b/libsolidity/Types.cpp index 04f86b922..ed3cb8fd1 100644 --- a/libsolidity/Types.cpp +++ b/libsolidity/Types.cpp @@ -20,14 +20,14 @@ * Solidity data types */ +#include +#include +#include #include #include #include -#include #include -#include - using namespace std; namespace dev @@ -812,6 +812,26 @@ u256 ContractType::getFunctionIdentifier(string const& _functionName) const return Invalid256; } +vector> ContractType::getStateVariables() const +{ + vector variables; + for (ContractDefinition const* contract: boost::adaptors::reverse(m_contract.getLinearizedBaseContracts())) + for (ASTPointer const& variable: contract->getStateVariables()) + if (!variable->isConstant()) + variables.push_back(variable.get()); + TypePointers types; + for (auto variable: variables) + types.push_back(variable->getType()); + StorageOffsets offsets; + offsets.computeOffsets(types); + + vector> variablesAndOffsets; + for (size_t index = 0; index < variables.size(); ++index) + if (auto const* offset = offsets.getOffset(index)) + variablesAndOffsets.push_back(make_tuple(variables[index], offset->first, offset->second)); + return variablesAndOffsets; +} + TypePointer StructType::unaryOperatorResult(Token::Value _operator) const { return _operator == Token::Delete ? make_shared() : TypePointer(); diff --git a/libsolidity/Types.h b/libsolidity/Types.h index e7601fde8..c7dbcdeb9 100644 --- a/libsolidity/Types.h +++ b/libsolidity/Types.h @@ -403,6 +403,10 @@ public: /// not exist. u256 getFunctionIdentifier(std::string const& _functionName) const; + /// @returns a list of all state variables (including inherited) of the contract and their + /// offsets in storage. + std::vector> getStateVariables() const; + private: ContractDefinition const& m_contract; /// If true, it is the "super" type of the current contract, i.e. it contains only inherited From 85505d45c01196e7f1733876dbf3c3f31fb2712a Mon Sep 17 00:00:00 2001 From: chriseth Date: Mon, 16 Mar 2015 17:52:19 +0100 Subject: [PATCH 02/66] Packing for arrays. --- libsolidity/ArrayUtils.cpp | 206 +++++++++++++++++++++++------ libsolidity/ArrayUtils.h | 6 + libsolidity/ExpressionCompiler.cpp | 71 ++++++---- libsolidity/Types.cpp | 18 ++- libsolidity/Types.h | 15 ++- test/SolidityEndToEndTest.cpp | 119 ++++++++++++++++- test/SolidityTypes.cpp | 11 ++ 7 files changed, 369 insertions(+), 77 deletions(-) diff --git a/libsolidity/ArrayUtils.cpp b/libsolidity/ArrayUtils.cpp index 2596e4afa..a46dea3c8 100644 --- a/libsolidity/ArrayUtils.cpp +++ b/libsolidity/ArrayUtils.cpp @@ -52,15 +52,21 @@ void ArrayUtils::copyArrayToStorage(ArrayType const& _targetType, ArrayType cons // TODO unroll loop for small sizes bool sourceIsStorage = _sourceType.getLocation() == ArrayType::Location::Storage; + bool directCopy = sourceIsStorage && sourceBaseType->isValueType() && *sourceBaseType == *targetBaseType; + bool haveByteOffsetSource = !directCopy && sourceIsStorage && sourceBaseType->getStorageBytes() <= 16; + bool haveByteOffsetTarget = !directCopy && targetBaseType->getStorageBytes() <= 16; + unsigned byteOffsetSize = (haveByteOffsetSource ? 1 : 0) + (haveByteOffsetTarget ? 1 : 0); // stack: source_ref [source_byte_off] [source_length] target_ref target_byte_off // store target_ref - m_context << eth::Instruction::POP; //@todo + // arrays always start at zero byte offset, pop offset + m_context << eth::Instruction::POP; for (unsigned i = _sourceType.getSizeOnStack(); i > 0; --i) m_context << eth::swapInstruction(i); // stack: target_ref source_ref [source_byte_off] [source_length] if (sourceIsStorage) - m_context << eth::Instruction::POP; //@todo + // arrays always start at zero byte offset, pop offset + m_context << eth::Instruction::POP; // stack: target_ref source_ref [source_length] // retrieve source length if (_sourceType.getLocation() != ArrayType::Location::CallData || !_sourceType.isDynamicallySized()) @@ -81,7 +87,7 @@ void ArrayUtils::copyArrayToStorage(ArrayType const& _targetType, ArrayType cons m_context << eth::Instruction::POP << eth::Instruction::POP << eth::Instruction::POP << eth::Instruction::POP; - m_context << u256(0); //@todo + m_context << u256(0); return; } // compute hashes (data positions) @@ -97,8 +103,8 @@ void ArrayUtils::copyArrayToStorage(ArrayType const& _targetType, ArrayType cons // stack: target_ref target_data_end source_length target_data_pos source_ref // skip copying if source length is zero m_context << eth::Instruction::DUP3 << eth::Instruction::ISZERO; - eth::AssemblyItem copyLoopEnd = m_context.newTag(); - m_context.appendConditionalJumpTo(copyLoopEnd); + eth::AssemblyItem copyLoopEndWithoutByteOffset = m_context.newTag(); + m_context.appendConditionalJumpTo(copyLoopEndWithoutByteOffset); if (_sourceType.getLocation() == ArrayType::Location::Storage && _sourceType.isDynamicallySized()) CompilerUtils(m_context).computeHashStatic(); @@ -107,18 +113,24 @@ void ArrayUtils::copyArrayToStorage(ArrayType const& _targetType, ArrayType cons convertLengthToSize(_sourceType); m_context << eth::Instruction::DUP3 << eth::Instruction::ADD; // stack: target_ref target_data_end source_data_pos target_data_pos source_data_end + if (haveByteOffsetTarget) + m_context << u256(0); + if (haveByteOffsetSource) + m_context << u256(0); + // stack: target_ref target_data_end source_data_pos target_data_pos source_data_end [target_byte_offset] [source_byte_offset] eth::AssemblyItem copyLoopStart = m_context.newTag(); m_context << copyLoopStart; // check for loop condition m_context - << eth::Instruction::DUP3 << eth::Instruction::DUP2 + << eth::dupInstruction(3 + byteOffsetSize) << eth::dupInstruction(2 + byteOffsetSize) << eth::Instruction::GT << eth::Instruction::ISZERO; + eth::AssemblyItem copyLoopEnd = m_context.newTag(); m_context.appendConditionalJumpTo(copyLoopEnd); - // stack: target_ref target_data_end source_data_pos target_data_pos source_data_end + // stack: target_ref target_data_end source_data_pos target_data_pos source_data_end [target_byte_offset] [source_byte_offset] // copy if (sourceBaseType->getCategory() == Type::Category::Array) { - //@todo + solAssert(byteOffsetSize == 0, "Byte offset for array as base type."); m_context << eth::Instruction::DUP3; if (sourceIsStorage) m_context << u256(0); @@ -129,36 +141,80 @@ void ArrayUtils::copyArrayToStorage(ArrayType const& _targetType, ArrayType cons ); m_context << eth::Instruction::POP << eth::Instruction::POP; } + else if (directCopy) + { + solAssert(byteOffsetSize == 0, "Byte offset for direct copy."); + m_context + << eth::Instruction::DUP3 << eth::Instruction::SLOAD + << eth::Instruction::DUP3 << eth::Instruction::SSTORE; + } else { - m_context << eth::Instruction::DUP3; + // Note that we have to copy each element on its own in case conversion is involved. + // We might copy too much if there is padding at the last element, but this way end + // checking is easier. + // stack: target_ref target_data_end source_data_pos target_data_pos source_data_end [target_byte_offset] [source_byte_offset] + m_context << eth::dupInstruction(3 + byteOffsetSize); if (_sourceType.getLocation() == ArrayType::Location::Storage) { - m_context << u256(0); + if (haveByteOffsetSource) + m_context << eth::Instruction::DUP2; + else + m_context << u256(0); StorageItem(m_context, *sourceBaseType).retrieveValue(SourceLocation(), true); } else if (sourceBaseType->isValueType()) CompilerUtils(m_context).loadFromMemoryDynamic(*sourceBaseType, true, true, false); else solAssert(false, "Copying of unknown type requested: " + sourceBaseType->toString()); - solAssert(2 + sourceBaseType->getSizeOnStack() <= 16, "Stack too deep."); - m_context << eth::dupInstruction(2 + sourceBaseType->getSizeOnStack()) << u256(0); + // stack: target_ref target_data_end source_data_pos target_data_pos source_data_end [target_byte_offset] [source_byte_offset] ... + solAssert(2 + byteOffsetSize + sourceBaseType->getSizeOnStack() <= 16, "Stack too deep."); + // fetch target storage reference + m_context << eth::dupInstruction(2 + byteOffsetSize + sourceBaseType->getSizeOnStack()); + if (haveByteOffsetTarget) + m_context << eth::dupInstruction(1 + byteOffsetSize + sourceBaseType->getSizeOnStack()); + else + m_context << u256(0); StorageItem(m_context, *targetBaseType).storeValue(*sourceBaseType, SourceLocation(), true); } + // stack: target_ref target_data_end source_data_pos target_data_pos source_data_end [target_byte_offset] [source_byte_offset] // increment source - m_context - << eth::Instruction::SWAP2 - << (sourceIsStorage ? sourceBaseType->getStorageSize() : sourceBaseType->getCalldataEncodedSize()) - << eth::Instruction::ADD - << eth::Instruction::SWAP2; + if (haveByteOffsetSource) + incrementByteOffset(sourceBaseType->getStorageBytes(), 1, haveByteOffsetTarget ? 5 : 4); + else + m_context + << eth::swapInstruction(2 + byteOffsetSize) + << (sourceIsStorage ? sourceBaseType->getStorageSize() : sourceBaseType->getCalldataEncodedSize()) + << eth::Instruction::ADD + << eth::swapInstruction(2 + byteOffsetSize); // increment target - m_context - << eth::Instruction::SWAP1 - << targetBaseType->getStorageSize() - << eth::Instruction::ADD - << eth::Instruction::SWAP1; + if (haveByteOffsetTarget) + incrementByteOffset(targetBaseType->getStorageBytes(), byteOffsetSize, byteOffsetSize + 2); + else + m_context + << eth::swapInstruction(1 + byteOffsetSize) + << targetBaseType->getStorageSize() + << eth::Instruction::ADD + << eth::swapInstruction(1 + byteOffsetSize); m_context.appendJumpTo(copyLoopStart); m_context << copyLoopEnd; + if (haveByteOffsetTarget) + { + // clear elements that might be left over in the current slot in target + // stack: target_ref target_data_end source_data_pos target_data_pos source_data_end target_byte_offset [source_byte_offset] + m_context << eth::dupInstruction(byteOffsetSize) << eth::Instruction::ISZERO; + eth::AssemblyItem copyCleanupLoopEnd = m_context.appendConditionalJump(); + m_context << eth::dupInstruction(2 + byteOffsetSize) << eth::dupInstruction(1 + byteOffsetSize); + StorageItem(m_context, *targetBaseType).setToZero(SourceLocation(), true); + incrementByteOffset(targetBaseType->getStorageBytes(), byteOffsetSize, byteOffsetSize + 2); + m_context.appendJumpTo(copyLoopEnd); + + m_context << copyCleanupLoopEnd; + m_context << eth::Instruction::POP; // might pop the source, but then target is popped next + } + if (haveByteOffsetSource) + m_context << eth::Instruction::POP; + m_context << copyLoopEndWithoutByteOffset; // zero-out leftovers in target // stack: target_ref target_data_end source_data_pos target_data_pos_updated source_data_end @@ -166,41 +222,61 @@ void ArrayUtils::copyArrayToStorage(ArrayType const& _targetType, ArrayType cons // stack: target_ref target_data_end target_data_pos_updated clearStorageLoop(*targetBaseType); m_context << eth::Instruction::POP; - m_context << u256(0); //@todo + m_context << u256(0); } void ArrayUtils::clearArray(ArrayType const& _type) const { unsigned stackHeightStart = m_context.getStackHeight(); solAssert(_type.getLocation() == ArrayType::Location::Storage, ""); - if (_type.isDynamicallySized()) + if (_type.getBaseType()->getStorageBytes() < 32) { - m_context << eth::Instruction::POP; // remove byte offset - clearDynamicArray(_type); + solAssert(_type.getBaseType()->isValueType(), "Invalid storage size for non-value type."); + solAssert(_type.getBaseType()->getStorageSize() <= 1, "Invalid storage size for type."); } + if (_type.getBaseType()->isValueType()) + solAssert(_type.getBaseType()->getStorageSize() <= 1, "Invalid size for value type."); + + m_context << eth::Instruction::POP; // remove byte offset + if (_type.isDynamicallySized()) + clearDynamicArray(_type); else if (_type.getLength() == 0 || _type.getBaseType()->getCategory() == Type::Category::Mapping) - m_context << eth::Instruction::POP << eth::Instruction::POP; - else if (_type.getLength() < 5) // unroll loop for small arrays @todo choose a good value + m_context << eth::Instruction::POP; + else if (_type.getBaseType()->isValueType() && _type.getStorageSize() <= 5) + { + // unroll loop for small arrays @todo choose a good value + // Note that we loop over storage slots here, not elements. + for (unsigned i = 1; i < _type.getStorageSize(); ++i) + m_context + << u256(0) << eth::Instruction::DUP2 << eth::Instruction::SSTORE + << u256(1) << eth::Instruction::ADD; + m_context << u256(0) << eth::Instruction::SWAP1 << eth::Instruction::SSTORE; + } + else if (!_type.getBaseType()->isValueType() && _type.getLength() <= 4) { - solAssert(!_type.isByteArray(), ""); + // unroll loop for small arrays @todo choose a good value + solAssert(_type.getBaseType()->getStorageBytes() >= 32, "Invalid storage size."); for (unsigned i = 1; i < _type.getLength(); ++i) { + m_context << u256(0); StorageItem(m_context, *_type.getBaseType()).setToZero(SourceLocation(), false); - m_context << eth::Instruction::SWAP1; - m_context << u256(_type.getBaseType()->getStorageSize()) << eth::Instruction::ADD; - m_context << eth::Instruction::SWAP1; + m_context + << eth::Instruction::POP + << u256(_type.getBaseType()->getStorageSize()) << eth::Instruction::ADD; } + m_context << u256(0); StorageItem(m_context, *_type.getBaseType()).setToZero(SourceLocation(), true); } else { - solAssert(!_type.isByteArray(), ""); - m_context << eth::Instruction::SWAP1; m_context << eth::Instruction::DUP1 << _type.getLength(); convertLengthToSize(_type); m_context << eth::Instruction::ADD << eth::Instruction::SWAP1; - clearStorageLoop(*_type.getBaseType()); - m_context << eth::Instruction::POP << eth::Instruction::POP; + if (_type.getBaseType()->getStorageBytes() < 32) + clearStorageLoop(IntegerType(256)); + else + clearStorageLoop(*_type.getBaseType()); + m_context << eth::Instruction::POP; } solAssert(m_context.getStackHeight() == stackHeightStart - 2, ""); } @@ -224,7 +300,7 @@ void ArrayUtils::clearDynamicArray(ArrayType const& _type) const m_context << eth::Instruction::SWAP1 << eth::Instruction::DUP2 << eth::Instruction::ADD << eth::Instruction::SWAP1; // stack: data_pos_end data_pos - if (_type.isByteArray()) + if (_type.isByteArray() || _type.getBaseType()->getStorageBytes() < 32) clearStorageLoop(IntegerType(256)); else clearStorageLoop(*_type.getBaseType()); @@ -237,6 +313,8 @@ void ArrayUtils::resizeDynamicArray(const ArrayType& _type) const { solAssert(_type.getLocation() == ArrayType::Location::Storage, ""); solAssert(_type.isDynamicallySized(), ""); + if (!_type.isByteArray() && _type.getBaseType()->getStorageBytes() < 32) + solAssert(_type.getBaseType()->isValueType(), "Invalid storage size for non-value type."); unsigned stackHeightStart = m_context.getStackHeight(); eth::AssemblyItem resizeEnd = m_context.newTag(); @@ -266,7 +344,7 @@ void ArrayUtils::resizeDynamicArray(const ArrayType& _type) const // stack: ref new_length data_pos new_size delete_end m_context << eth::Instruction::SWAP2 << eth::Instruction::ADD; // stack: ref new_length delete_end delete_start - if (_type.isByteArray()) + if (_type.isByteArray() || _type.getBaseType()->getStorageBytes() < 32) clearStorageLoop(IntegerType(256)); else clearStorageLoop(*_type.getBaseType()); @@ -294,7 +372,7 @@ void ArrayUtils::clearStorageLoop(Type const& _type) const eth::AssemblyItem zeroLoopEnd = m_context.newTag(); m_context.appendConditionalJumpTo(zeroLoopEnd); // delete - m_context << u256(0); //@todo + m_context << u256(0); StorageItem(m_context, _type).setToZero(SourceLocation(), false); m_context << eth::Instruction::POP; // increment @@ -313,7 +391,20 @@ void ArrayUtils::convertLengthToSize(ArrayType const& _arrayType, bool _pad) con if (_arrayType.isByteArray()) m_context << u256(31) << eth::Instruction::ADD << u256(32) << eth::Instruction::SWAP1 << eth::Instruction::DIV; - else if (_arrayType.getBaseType()->getStorageSize() > 1) + else if (_arrayType.getBaseType()->getStorageSize() <= 1) + { + unsigned baseBytes = _arrayType.getBaseType()->getStorageBytes(); + if (baseBytes == 0) + m_context << eth::Instruction::POP << u256(1); + else if (baseBytes <= 16) + { + unsigned itemsPerSlot = 32 / baseBytes; + m_context + << u256(itemsPerSlot - 1) << eth::Instruction::ADD + << u256(itemsPerSlot) << eth::Instruction::SWAP1 << eth::Instruction::DIV; + } + } + else m_context << _arrayType.getBaseType()->getStorageSize() << eth::Instruction::MUL; } else @@ -349,3 +440,38 @@ void ArrayUtils::retrieveLength(ArrayType const& _arrayType) const } } +void ArrayUtils::incrementByteOffset(unsigned byteSize, unsigned byteOffsetPosition, unsigned storageOffsetPosition) const +{ + solAssert(byteSize < 32, ""); + // We do the following, but avoiding jumps: + // byteOffset += byteSize + // if (byteOffset + byteSize > 32) + // { + // storageOffset++; + // byteOffset = 0; + // } + if (byteOffsetPosition > 1) + m_context << eth::swapInstruction(byteOffsetPosition - 1); + m_context << u256(byteSize) << eth::Instruction::ADD; + if (byteOffsetPosition > 1) + m_context << eth::swapInstruction(byteOffsetPosition - 1); + // compute, X := (byteOffset + byteSize - 1) / 32, should be 1 iff byteOffset + bytesize > 32 + m_context + << u256(32) << eth::dupInstruction(1 + byteOffsetPosition) << u256(byteSize - 1) + << eth::Instruction::ADD << eth::Instruction::DIV; + // increment storage offset if X == 1 (just add X to it) + // stack: X + m_context + << eth::swapInstruction(storageOffsetPosition) << eth::dupInstruction(storageOffsetPosition + 1) + << eth::Instruction::ADD << eth::swapInstruction(storageOffsetPosition); + // stack: X + // set source_byte_offset to zero if X == 1 (using source_byte_offset *= 1 - X) + m_context << u256(1) << eth::Instruction::SUB; + // stack: 1 - X + if (byteOffsetPosition == 1) + m_context << eth::Instruction::MUL; + else + m_context + << eth::dupInstruction(byteOffsetPosition + 1) << eth::Instruction::MUL + << eth::swapInstruction(byteOffsetPosition) << eth::Instruction::POP; +} diff --git a/libsolidity/ArrayUtils.h b/libsolidity/ArrayUtils.h index c7b05b6d3..6e4ceec1c 100644 --- a/libsolidity/ArrayUtils.h +++ b/libsolidity/ArrayUtils.h @@ -72,6 +72,12 @@ public: void retrieveLength(ArrayType const& _arrayType) const; private: + /// Adds the given number of bytes to a storage byte offset counter and also increments + /// the storage offset if adding this number again would increase the counter over 32. + /// @param byteOffsetPosition the stack offset of the storage byte offset + /// @param storageOffsetPosition the stack offset of the storage slot offset + void incrementByteOffset(unsigned byteSize, unsigned byteOffsetPosition, unsigned storageOffsetPosition) const; + CompilerContext& m_context; }; diff --git a/libsolidity/ExpressionCompiler.cpp b/libsolidity/ExpressionCompiler.cpp index 61b17f663..144827d44 100644 --- a/libsolidity/ExpressionCompiler.cpp +++ b/libsolidity/ExpressionCompiler.cpp @@ -753,7 +753,6 @@ bool ExpressionCompiler::visit(IndexAccess const& _indexAccess) } else if (baseType.getCategory() == Type::Category::Array) { - // stack layout: [storage_byte_offset] [] ArrayType const& arrayType = dynamic_cast(baseType); solAssert(_indexAccess.getIndexExpression(), "Index expression expected."); ArrayType::Location location = arrayType.getLocation(); @@ -762,6 +761,11 @@ bool ExpressionCompiler::visit(IndexAccess const& _indexAccess) location == ArrayType::Location::Memory ? eth::Instruction::MLOAD : eth::Instruction::CALLDATALOAD; + // remove storage byte offset + if (location == ArrayType::Location::Storage) + m_context << eth::Instruction::POP; + + // stack layout: [] _indexAccess.getIndexExpression()->accept(*this); // retrieve length if (!arrayType.isDynamicallySized()) @@ -769,11 +773,9 @@ bool ExpressionCompiler::visit(IndexAccess const& _indexAccess) else if (location == ArrayType::Location::CallData) // length is stored on the stack m_context << eth::Instruction::SWAP1; - else if (location == ArrayType::Location::Storage) - m_context << eth::Instruction::DUP3 << load; else m_context << eth::Instruction::DUP2 << load; - // stack: [storage_byte_offset] + // stack: // check out-of-bounds access m_context << eth::Instruction::DUP2 << eth::Instruction::LT; eth::AssemblyItem legalAccess = m_context.appendConditionalJump(); @@ -781,23 +783,22 @@ bool ExpressionCompiler::visit(IndexAccess const& _indexAccess) m_context << eth::Instruction::STOP; m_context << legalAccess; - // stack: [storage_byte_offset] + // stack: if (arrayType.isByteArray()) - // byte array is packed differently, especially in storage switch (location) { case ArrayType::Location::Storage: // byte array index storage lvalue on stack (goal): // = - m_context << u256(32) << eth::Instruction::SWAP3; + m_context << u256(32) << eth::Instruction::SWAP2; CompilerUtils(m_context).computeHashStatic(); - // stack: 32 storage_byte_offset index data_ref + // stack: 32 index data_ref m_context - << eth::Instruction::DUP4 << eth::Instruction::DUP3 + << eth::Instruction::DUP3 << eth::Instruction::DUP3 << eth::Instruction::DIV << eth::Instruction::ADD - // stack: 32 storage_byte_offset index (data_ref + index / 32) - << eth::Instruction::SWAP3 << eth::Instruction::SWAP2 - << eth::Instruction::POP << eth::Instruction::MOD; + // stack: 32 index (data_ref + index / 32) + << eth::Instruction::SWAP2 << eth::Instruction::SWAP1 + << eth::Instruction::MOD; setLValue(_indexAccess); break; case ArrayType::Location::CallData: @@ -811,36 +812,50 @@ bool ExpressionCompiler::visit(IndexAccess const& _indexAccess) } else { - // stack: [storage_byte_offset] - if (location == ArrayType::Location::Storage) - //@todo use byte offset, remove it for now - m_context << eth::Instruction::SWAP1 << eth::Instruction::POP; - u256 elementSize = - location == ArrayType::Location::Storage ? - arrayType.getBaseType()->getStorageSize() : - arrayType.getBaseType()->getCalldataEncodedSize(); - solAssert(elementSize != 0, "Invalid element size."); - if (elementSize > 1) - m_context << elementSize << eth::Instruction::MUL; + // stack: + m_context << eth::Instruction::SWAP1; if (arrayType.isDynamicallySized()) { if (location == ArrayType::Location::Storage) - { - m_context << eth::Instruction::SWAP1; CompilerUtils(m_context).computeHashStatic(); - } else if (location == ArrayType::Location::Memory) m_context << u256(32) << eth::Instruction::ADD; } - m_context << eth::Instruction::ADD; + // stack: switch (location) { case ArrayType::Location::CallData: + m_context + << eth::Instruction::SWAP1 << arrayType.getBaseType()->getCalldataEncodedSize() + << eth::Instruction::MUL << eth::Instruction::ADD; if (arrayType.getBaseType()->isValueType()) CompilerUtils(m_context).loadFromMemoryDynamic(*arrayType.getBaseType(), true, true, false); break; case ArrayType::Location::Storage: - m_context << u256(0); // @todo + m_context << eth::Instruction::SWAP1; + if (arrayType.getBaseType()->getStorageBytes() <= 16) + { + // stack: + // goal: + // = <(index % itemsPerSlot) * byteSize> + unsigned byteSize = arrayType.getBaseType()->getStorageBytes(); + unsigned itemsPerSlot = 32 / byteSize; + m_context << u256(itemsPerSlot) << eth::Instruction::SWAP2; + // stack: itemsPerSlot index data_ref + m_context + << eth::Instruction::DUP3 << eth::Instruction::DUP3 + << eth::Instruction::DIV << eth::Instruction::ADD + // stack: itemsPerSlot index (data_ref + index / itemsPerSlot) + << eth::Instruction::SWAP2 << eth::Instruction::SWAP1 + << eth::Instruction::MOD + << u256(byteSize) << eth::Instruction::MUL; + } + else + { + if (arrayType.getBaseType()->getStorageSize() != 1) + m_context << arrayType.getBaseType()->getStorageSize() << eth::Instruction::MUL; + m_context << eth::Instruction::ADD << u256(0); + } setLValueToStorageItem(_indexAccess); break; case ArrayType::Location::Memory: diff --git a/libsolidity/Types.cpp b/libsolidity/Types.cpp index ed3cb8fd1..14ea4c73c 100644 --- a/libsolidity/Types.cpp +++ b/libsolidity/Types.cpp @@ -706,13 +706,21 @@ u256 ArrayType::getStorageSize() const { if (isDynamicallySized()) return 1; - else + + bigint size; + unsigned baseBytes = getBaseType()->getStorageBytes(); + if (baseBytes == 0) + size = 1; + else if (baseBytes < 32) { - bigint size = bigint(getLength()) * getBaseType()->getStorageSize(); - if (size >= bigint(1) << 256) - BOOST_THROW_EXCEPTION(TypeError() << errinfo_comment("Array too large for storage.")); - return max(1, u256(size)); + unsigned itemsPerSlot = 32 / baseBytes; + size = (bigint(getLength()) + (itemsPerSlot - 1)) / itemsPerSlot; } + else + size = bigint(getLength()) * getBaseType()->getStorageSize(); + if (size >= bigint(1) << 256) + BOOST_THROW_EXCEPTION(TypeError() << errinfo_comment("Array too large for storage.")); + return max(1, u256(size)); } unsigned ArrayType::getSizeOnStack() const diff --git a/libsolidity/Types.h b/libsolidity/Types.h index c7dbcdeb9..c90aabda1 100644 --- a/libsolidity/Types.h +++ b/libsolidity/Types.h @@ -335,13 +335,22 @@ public: /// Constructor for a byte array ("bytes") explicit ArrayType(Location _location): - m_location(_location), m_isByteArray(true), m_baseType(std::make_shared(8)) {} + m_location(_location), + m_isByteArray(true), + m_baseType(std::make_shared(8)) + {} /// Constructor for a dynamically sized array type ("type[]") ArrayType(Location _location, const TypePointer &_baseType): - m_location(_location), m_baseType(_baseType) {} + m_location(_location), + m_baseType(_baseType) + {} /// Constructor for a fixed-size array type ("type[20]") ArrayType(Location _location, const TypePointer &_baseType, u256 const& _length): - m_location(_location), m_baseType(_baseType), m_hasDynamicLength(false), m_length(_length) {} + m_location(_location), + m_baseType(_baseType), + m_hasDynamicLength(false), + m_length(_length) + {} virtual bool isImplicitlyConvertibleTo(Type const& _convertTo) const override; virtual TypePointer unaryOperatorResult(Token::Value _operator) const override; diff --git a/test/SolidityEndToEndTest.cpp b/test/SolidityEndToEndTest.cpp index ce7a472bc..48ad183ae 100644 --- a/test/SolidityEndToEndTest.cpp +++ b/test/SolidityEndToEndTest.cpp @@ -3040,6 +3040,123 @@ BOOST_AUTO_TEST_CASE(array_copy_storage_storage_static_dynamic) BOOST_CHECK(callContractFunction("test()") == encodeArgs(9, 4)); } +BOOST_AUTO_TEST_CASE(array_copy_different_packing) +{ + char const* sourceCode = R"( + contract c { + bytes8[] data1; // 4 per slot + bytes10[] data2; // 3 per slot + function test() returns (bytes10 a, bytes10 b, bytes10 c, bytes10 d, bytes10 e) { + data1.length = 9; + for (uint i = 0; i < data1.length; ++i) + data1[i] = bytes8(i); + data2 = data1; + a = data2[1]; + b = data2[2]; + c = data2[3]; + d = data2[4]; + e = data2[5]; + } + } + )"; + compileAndRun(sourceCode); + BOOST_CHECK(callContractFunction("test()") == encodeArgs( + asString(fromHex("0000000000000001")), + asString(fromHex("0000000000000002")), + asString(fromHex("0000000000000003")), + asString(fromHex("0000000000000004")), + asString(fromHex("0000000000000005")) + )); +} + +BOOST_AUTO_TEST_CASE(array_copy_target_simple) +{ + char const* sourceCode = R"( + contract c { + bytes8[9] data1; // 4 per slot + bytes17[10] data2; // 1 per slot, no offset counter + function test() returns (bytes17 a, bytes17 b, bytes17 c, bytes17 d, bytes17 e) { + for (uint i = 0; i < data1.length; ++i) + data1[i] = bytes8(i); + data2[8] = data2[9] = 2; + data2 = data1; + a = data2[1]; + b = data2[2]; + c = data2[3]; + d = data2[4]; + e = data2[9]; + } + } + )"; + compileAndRun(sourceCode); + BOOST_CHECK(callContractFunction("test()") == encodeArgs( + asString(fromHex("0000000000000001")), + asString(fromHex("0000000000000002")), + asString(fromHex("0000000000000003")), + asString(fromHex("0000000000000004")), + asString(fromHex("0000000000000000")) + )); +} + +BOOST_AUTO_TEST_CASE(array_copy_target_leftover) +{ + // test that leftover elements in the last slot of target are correctly cleared during assignment + char const* sourceCode = R"( + contract c { + byte[10] data1; + bytes2[32] data2; + function test() returns (uint check, uint res1, uint res2) { + uint i; + for (i = 0; i < data2.length; ++i) + data2[i] = 0xffff; + check = uint(data2[31]) * 0x10000 | uint(data2[14]); + for (i = 0; i < data1.length; ++i) + data1[i] = byte(uint8(1 + i)); + data2 = data1; + for (i = 0; i < 16; ++i) + res1 |= uint(data2[i]) * 0x10000**i; + for (i = 0; i < 16; ++i) + res2 |= uint(data2[16 + i]) * 0x10000**i; + } + } + )"; + compileAndRun(sourceCode); + BOOST_CHECK(callContractFunction("test()") == encodeArgs( + u256("0xffffffff"), + asString(fromHex("0000000000000000""000000000a000900""0800070006000500""0400030002000100")), + asString(fromHex("0000000000000000""0000000000000000""0000000000000000""0000000000000000")) + )); +} + +BOOST_AUTO_TEST_CASE(array_copy_target_leftover2) +{ + // since the copy always copies whole slots, we have to make sure that the source size maxes + // out a whole slot and at the same time there are still elements left in the target at that point + char const* sourceCode = R"( + contract c { + bytes8[4] data1; // fits into one slot + bytes10[6] data2; // 4 elements need two slots + function test() returns (bytes10 r1, bytes10 r2, bytes10 r3) { + data1[0] = 1; + data1[1] = 2; + data1[2] = 3; + data1[3] = 4; + for (uint i = 0; i < data2.length; ++i) + data2[i] = bytes10(0xffff00 | (1 + i)); + data2 = data1; + r1 = data2[3]; + r2 = data2[4]; + r3 = data2[5]; + } + } + )"; + compileAndRun(sourceCode); + BOOST_CHECK(callContractFunction("test()") == encodeArgs( + asString(fromHex("0000000000000004")), + asString(fromHex("0000000000000000")), + asString(fromHex("0000000000000000")) + )); +} BOOST_AUTO_TEST_CASE(array_copy_storage_storage_struct) { char const* sourceCode = R"( @@ -3166,7 +3283,7 @@ BOOST_AUTO_TEST_CASE(array_copy_nested_array) char const* sourceCode = R"( contract c { uint[4][] a; - uint[5][] b; + uint[10][] b; uint[][] c; function test(uint[2][] d) external returns (uint) { a = d; diff --git a/test/SolidityTypes.cpp b/test/SolidityTypes.cpp index 8defd1d89..6b6306479 100644 --- a/test/SolidityTypes.cpp +++ b/test/SolidityTypes.cpp @@ -75,6 +75,17 @@ BOOST_AUTO_TEST_CASE(storage_layout_mapping) BOOST_CHECK(*members.getMemberStorageOffset("final") == make_pair(u256(3), unsigned(0))); } +BOOST_AUTO_TEST_CASE(storage_layout_arrays) +{ + BOOST_CHECK(ArrayType(ArrayType::Location::Storage, make_shared(1), 32).getStorageSize() == 1); + BOOST_CHECK(ArrayType(ArrayType::Location::Storage, make_shared(1), 33).getStorageSize() == 2); + BOOST_CHECK(ArrayType(ArrayType::Location::Storage, make_shared(2), 31).getStorageSize() == 2); + BOOST_CHECK(ArrayType(ArrayType::Location::Storage, make_shared(7), 8).getStorageSize() == 2); + BOOST_CHECK(ArrayType(ArrayType::Location::Storage, make_shared(7), 9).getStorageSize() == 3); + BOOST_CHECK(ArrayType(ArrayType::Location::Storage, make_shared(31), 9).getStorageSize() == 9); + BOOST_CHECK(ArrayType(ArrayType::Location::Storage, make_shared(32), 9).getStorageSize() == 9); +} + BOOST_AUTO_TEST_SUITE_END() } From 523ce4d178933120e71bb9097e07cc13021459ae Mon Sep 17 00:00:00 2001 From: chriseth Date: Tue, 17 Mar 2015 18:34:57 +0100 Subject: [PATCH 03/66] Disallowed special case of bytes0 arrays. --- libsolidity/Types.cpp | 2 ++ test/SolidityEndToEndTest.cpp | 24 ++++++++++++++++++++++++ test/SolidityNameAndTypeResolution.cpp | 10 ++++++++++ 3 files changed, 36 insertions(+) diff --git a/libsolidity/Types.cpp b/libsolidity/Types.cpp index 14ea4c73c..a718ee4f9 100644 --- a/libsolidity/Types.cpp +++ b/libsolidity/Types.cpp @@ -184,6 +184,8 @@ TypePointer Type::fromArrayTypeName(TypeName& _baseTypeName, Expression* _length TypePointer baseType = _baseTypeName.toType(); if (!baseType) BOOST_THROW_EXCEPTION(_baseTypeName.createTypeError("Invalid type name.")); + if (baseType->getStorageBytes() == 0) + BOOST_THROW_EXCEPTION(_baseTypeName.createTypeError("Illegal base type of storage size zero for array.")); if (_length) { if (!_length->getType()) diff --git a/test/SolidityEndToEndTest.cpp b/test/SolidityEndToEndTest.cpp index 48ad183ae..cbcff405b 100644 --- a/test/SolidityEndToEndTest.cpp +++ b/test/SolidityEndToEndTest.cpp @@ -3549,6 +3549,30 @@ BOOST_AUTO_TEST_CASE(packed_storage_structs_delete) BOOST_CHECK(m_state.storage(m_contractAddress).empty()); } +BOOST_AUTO_TEST_CASE(packed_storage_structs_with_bytes0) +{ + char const* sourceCode = R"( + contract C { + struct str { uint8 a; bytes0 b; uint8 c; } + uint8 a; + bytes0 x; + uint8 b; + str data; + function test() returns (bool) { + a = 2; + b = 3; + data.a = 4; + data.c = 5; + delete x; + delete data.b; + return a == 2 && b == 3 && data.a == 4 && data.c == 5; + } + } + )"; + compileAndRun(sourceCode); + BOOST_CHECK(callContractFunction("test()") == encodeArgs(true)); +} + BOOST_AUTO_TEST_SUITE_END() } diff --git a/test/SolidityNameAndTypeResolution.cpp b/test/SolidityNameAndTypeResolution.cpp index b83709d83..591cf053a 100644 --- a/test/SolidityNameAndTypeResolution.cpp +++ b/test/SolidityNameAndTypeResolution.cpp @@ -1446,6 +1446,16 @@ BOOST_AUTO_TEST_CASE(local_const_variable) BOOST_CHECK_THROW(parseTextAndResolveNames(text), ParserError); } +BOOST_AUTO_TEST_CASE(bytes0_array) +{ + char const* text = R"( + contract Foo { + bytes0[] illegalArray; + } + )"; + BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError); +} + BOOST_AUTO_TEST_SUITE_END() } From d2077b8962a084651b0f40fde79c91e0bc9923a4 Mon Sep 17 00:00:00 2001 From: chriseth Date: Thu, 19 Mar 2015 18:15:16 +0100 Subject: [PATCH 04/66] Byte size checked for zero; coding style. --- libsolidity/ArrayUtils.cpp | 27 ++++++++++++++------------- libsolidity/ArrayUtils.h | 2 +- libsolidity/ExpressionCompiler.cpp | 1 + 3 files changed, 16 insertions(+), 14 deletions(-) diff --git a/libsolidity/ArrayUtils.cpp b/libsolidity/ArrayUtils.cpp index a46dea3c8..bbf7f985a 100644 --- a/libsolidity/ArrayUtils.cpp +++ b/libsolidity/ArrayUtils.cpp @@ -440,9 +440,10 @@ void ArrayUtils::retrieveLength(ArrayType const& _arrayType) const } } -void ArrayUtils::incrementByteOffset(unsigned byteSize, unsigned byteOffsetPosition, unsigned storageOffsetPosition) const +void ArrayUtils::incrementByteOffset(unsigned _byteSize, unsigned _byteOffsetPosition, unsigned _storageOffsetPosition) const { - solAssert(byteSize < 32, ""); + solAssert(_byteSize < 32, ""); + solAssert(_byteSize != 0, ""); // We do the following, but avoiding jumps: // byteOffset += byteSize // if (byteOffset + byteSize > 32) @@ -450,28 +451,28 @@ void ArrayUtils::incrementByteOffset(unsigned byteSize, unsigned byteOffsetPosit // storageOffset++; // byteOffset = 0; // } - if (byteOffsetPosition > 1) - m_context << eth::swapInstruction(byteOffsetPosition - 1); - m_context << u256(byteSize) << eth::Instruction::ADD; - if (byteOffsetPosition > 1) - m_context << eth::swapInstruction(byteOffsetPosition - 1); + if (_byteOffsetPosition > 1) + m_context << eth::swapInstruction(_byteOffsetPosition - 1); + m_context << u256(_byteSize) << eth::Instruction::ADD; + if (_byteOffsetPosition > 1) + m_context << eth::swapInstruction(_byteOffsetPosition - 1); // compute, X := (byteOffset + byteSize - 1) / 32, should be 1 iff byteOffset + bytesize > 32 m_context - << u256(32) << eth::dupInstruction(1 + byteOffsetPosition) << u256(byteSize - 1) + << u256(32) << eth::dupInstruction(1 + _byteOffsetPosition) << u256(_byteSize - 1) << eth::Instruction::ADD << eth::Instruction::DIV; // increment storage offset if X == 1 (just add X to it) // stack: X m_context - << eth::swapInstruction(storageOffsetPosition) << eth::dupInstruction(storageOffsetPosition + 1) - << eth::Instruction::ADD << eth::swapInstruction(storageOffsetPosition); + << eth::swapInstruction(_storageOffsetPosition) << eth::dupInstruction(_storageOffsetPosition + 1) + << eth::Instruction::ADD << eth::swapInstruction(_storageOffsetPosition); // stack: X // set source_byte_offset to zero if X == 1 (using source_byte_offset *= 1 - X) m_context << u256(1) << eth::Instruction::SUB; // stack: 1 - X - if (byteOffsetPosition == 1) + if (_byteOffsetPosition == 1) m_context << eth::Instruction::MUL; else m_context - << eth::dupInstruction(byteOffsetPosition + 1) << eth::Instruction::MUL - << eth::swapInstruction(byteOffsetPosition) << eth::Instruction::POP; + << eth::dupInstruction(_byteOffsetPosition + 1) << eth::Instruction::MUL + << eth::swapInstruction(_byteOffsetPosition) << eth::Instruction::POP; } diff --git a/libsolidity/ArrayUtils.h b/libsolidity/ArrayUtils.h index 6e4ceec1c..22c0646a5 100644 --- a/libsolidity/ArrayUtils.h +++ b/libsolidity/ArrayUtils.h @@ -76,7 +76,7 @@ private: /// the storage offset if adding this number again would increase the counter over 32. /// @param byteOffsetPosition the stack offset of the storage byte offset /// @param storageOffsetPosition the stack offset of the storage slot offset - void incrementByteOffset(unsigned byteSize, unsigned byteOffsetPosition, unsigned storageOffsetPosition) const; + void incrementByteOffset(unsigned _byteSize, unsigned _byteOffsetPosition, unsigned _storageOffsetPosition) const; CompilerContext& m_context; }; diff --git a/libsolidity/ExpressionCompiler.cpp b/libsolidity/ExpressionCompiler.cpp index 144827d44..da762147a 100644 --- a/libsolidity/ExpressionCompiler.cpp +++ b/libsolidity/ExpressionCompiler.cpp @@ -839,6 +839,7 @@ bool ExpressionCompiler::visit(IndexAccess const& _indexAccess) // goal: // = <(index % itemsPerSlot) * byteSize> unsigned byteSize = arrayType.getBaseType()->getStorageBytes(); + solAssert(byteSize != 0, ""); unsigned itemsPerSlot = 32 / byteSize; m_context << u256(itemsPerSlot) << eth::Instruction::SWAP2; // stack: itemsPerSlot index data_ref From a180a5b3397a7f16f5c745375f6aae2ae1c08152 Mon Sep 17 00:00:00 2001 From: winsvega Date: Thu, 19 Mar 2015 23:17:27 +0300 Subject: [PATCH 05/66] SDIV YP p.22 Test Case --- test/blockchain.cpp | 4 +-- test/vmArithmeticTestFiller.json | 58 +++++++++++++++++++++++++++++++- 2 files changed, 59 insertions(+), 3 deletions(-) diff --git a/test/blockchain.cpp b/test/blockchain.cpp index 5ad395499..0f5eeaee2 100644 --- a/test/blockchain.cpp +++ b/test/blockchain.cpp @@ -653,9 +653,9 @@ BOOST_AUTO_TEST_CASE(bcUncleTest) dev::test::executeTests("bcUncleTest", "/BlockTests", dev::test::doBlockchainTests); } -BOOST_AUTO_TEST_CASE(userDefinedFileBc) +BOOST_AUTO_TEST_CASE(userDefinedFile) { - dev::test::userDefinedTest("--bctest", dev::test::doBlockchainTests); + dev::test::userDefinedTest("--singletest", dev::test::doBlockchainTests); } BOOST_AUTO_TEST_SUITE_END() diff --git a/test/vmArithmeticTestFiller.json b/test/vmArithmeticTestFiller.json index df3fa84f5..b05b5f5f6 100644 --- a/test/vmArithmeticTestFiller.json +++ b/test/vmArithmeticTestFiller.json @@ -925,6 +925,62 @@ } }, + "sdiv5": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "1000000", + "currentDifficulty" : "256", + "currentTimestamp" : "1", + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "{ [[ 0 ]] (SDIV (- 0 57896044618658097711785492504343953926634992332820282019728792003956564819968) (- 0 1) ) }", + "storage": {} + } + }, + "exec" : { + "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "origin" : "cd1722f2947def4cf144679da39c4c32bdc35681", + "caller" : "cd1722f2947def4cf144679da39c4c32bdc35681", + "value" : "1000000000000000000", + "data" : "", + "gasPrice" : "100000000000000", + "gas" : "100000" + } + }, + + "sdiv6": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "1000000", + "currentDifficulty" : "256", + "currentTimestamp" : "1", + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "{ [[ 0 ]] (SDIV (- 0 57896044618658097711785492504343953926634992332820282019728792003956564819968) 0 ) }", + "storage": {} + } + }, + "exec" : { + "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "origin" : "cd1722f2947def4cf144679da39c4c32bdc35681", + "caller" : "cd1722f2947def4cf144679da39c4c32bdc35681", + "value" : "1000000000000000000", + "data" : "", + "gasPrice" : "100000000000000", + "gas" : "100000" + } + }, + "sdiv_i256min": { "env" : { "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", @@ -977,7 +1033,7 @@ "value" : "1000000000000000000", "data" : "", "gasPrice" : "100000000000000", - "gas" : "10000" + "gas" : "100000" } }, From 642a8c9feaf9270f9b3e87ffb93680539a0a91f6 Mon Sep 17 00:00:00 2001 From: winsvega Date: Thu, 19 Mar 2015 23:56:03 +0300 Subject: [PATCH 06/66] Arithmetic Tests More Tests --- test/vmArithmeticTestFiller.json | 84 ++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) diff --git a/test/vmArithmeticTestFiller.json b/test/vmArithmeticTestFiller.json index b05b5f5f6..1af2964f6 100644 --- a/test/vmArithmeticTestFiller.json +++ b/test/vmArithmeticTestFiller.json @@ -981,6 +981,90 @@ } }, + "sdiv7": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "1000000", + "currentDifficulty" : "256", + "currentTimestamp" : "1", + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "{ [[ 0 ]] (SDIV (- 0 1) 25 ) }", + "storage": {} + } + }, + "exec" : { + "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "origin" : "cd1722f2947def4cf144679da39c4c32bdc35681", + "caller" : "cd1722f2947def4cf144679da39c4c32bdc35681", + "value" : "1000000000000000000", + "data" : "", + "gasPrice" : "100000000000000", + "gas" : "100000" + } + }, + + "sdiv8": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "1000000", + "currentDifficulty" : "256", + "currentTimestamp" : "1", + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "{ [[ 0 ]] (SDIV (- 0 1) (- 0 1)) }", + "storage": {} + } + }, + "exec" : { + "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "origin" : "cd1722f2947def4cf144679da39c4c32bdc35681", + "caller" : "cd1722f2947def4cf144679da39c4c32bdc35681", + "value" : "1000000000000000000", + "data" : "", + "gasPrice" : "100000000000000", + "gas" : "100000" + } + }, + + "sdiv9": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "1000000", + "currentDifficulty" : "256", + "currentTimestamp" : "1", + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "{ [[ 0 ]] (SDIV (- 0 1) 1) }", + "storage": {} + } + }, + "exec" : { + "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "origin" : "cd1722f2947def4cf144679da39c4c32bdc35681", + "caller" : "cd1722f2947def4cf144679da39c4c32bdc35681", + "value" : "1000000000000000000", + "data" : "", + "gasPrice" : "100000000000000", + "gas" : "100000" + } + }, + "sdiv_i256min": { "env" : { "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", From a78eee58613dd3e0968608ca3ec3bdb968734552 Mon Sep 17 00:00:00 2001 From: subtly Date: Fri, 20 Mar 2015 04:09:32 +0100 Subject: [PATCH 07/66] bump discovery version --- libp2p/NodeTable.cpp | 7 +++++++ libp2p/NodeTable.h | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/libp2p/NodeTable.cpp b/libp2p/NodeTable.cpp index ccfbeaba4..0f51b29cf 100644 --- a/libp2p/NodeTable.cpp +++ b/libp2p/NodeTable.cpp @@ -463,6 +463,13 @@ void NodeTable::onReceived(UDPSocketFace*, bi::udp::endpoint const& _from, bytes case PingNode::type: { PingNode in = PingNode::fromBytesConstRef(_from, rlpBytes); + if (in.version != 0x2) + { + if (auto n = nodeEntry(nodeid)) + dropNode(n); + return; + } + addNode(nodeid, _from, bi::tcp::endpoint(bi::address::from_string(in.ipAddress), in.port)); Pong p(_from); diff --git a/libp2p/NodeTable.h b/libp2p/NodeTable.h index a97326501..fbeb53a2d 100644 --- a/libp2p/NodeTable.h +++ b/libp2p/NodeTable.h @@ -315,7 +315,7 @@ struct PingNode: RLPXDatagram static const uint8_t type = 1; - unsigned version = 1; + unsigned version = 2; std::string ipAddress; unsigned port; unsigned expiration; From 2d75cd4f724905cd288b5036a1e1612f448de2cb Mon Sep 17 00:00:00 2001 From: chriseth Date: Fri, 20 Mar 2015 13:00:43 +0100 Subject: [PATCH 08/66] Fixed clang warning. --- libethereum/Transaction.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libethereum/Transaction.h b/libethereum/Transaction.h index 85543a3fc..8cb6cb7fc 100644 --- a/libethereum/Transaction.h +++ b/libethereum/Transaction.h @@ -66,7 +66,7 @@ enum class CodeDeposit Success }; -class VMException; +struct VMException; TransactionException toTransactionException(VMException const& _e); From 2c9c4bac2275bd8fdb6da0f89904c2f05fbe0206 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Fri, 20 Mar 2015 16:40:29 +0100 Subject: [PATCH 09/66] Fixes #1354. --- alethzero/Transact.cpp | 1 + libweb3jsonrpc/WebThreeStubServerBase.cpp | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/alethzero/Transact.cpp b/alethzero/Transact.cpp index 2c77895ff..d89b2ef3c 100644 --- a/alethzero/Transact.cpp +++ b/alethzero/Transact.cpp @@ -284,6 +284,7 @@ void Transact::on_send_clicked() { // If execution is a contract creation, add Natspec to // a local Natspec LEVELDB + ExecutionResult er = ethereum()->create(s, value(), m_data, ui->gas->value(), gasPrice()); ethereum()->submitTransaction(s, value(), m_data, ui->gas->value(), gasPrice()); string src = ui->data->toPlainText().toStdString(); if (sourceIsSolidity(src)) diff --git a/libweb3jsonrpc/WebThreeStubServerBase.cpp b/libweb3jsonrpc/WebThreeStubServerBase.cpp index 76b422a18..6424354f2 100644 --- a/libweb3jsonrpc/WebThreeStubServerBase.cpp +++ b/libweb3jsonrpc/WebThreeStubServerBase.cpp @@ -476,7 +476,7 @@ string WebThreeStubServerBase::eth_call(Json::Value const& _json, string const& t.gasPrice = 10 * dev::eth::szabo; if (!t.gas) t.gas = min(client()->gasLimitRemaining(), client()->balanceAt(t.from) / t.gasPrice); - ret = toJS(client()->call(m_accounts->secretKey(t.from), t.value, t.to, t.data, t.gas, t.gasPrice, number)); + ret = toJS(client()->call(m_accounts->secretKey(t.from), t.value, t.to, t.data, t.gas, t.gasPrice, number).output); return ret; } From 7b6710ac5b780c40b7ff9c492eae9b44508bb279 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Fri, 20 Mar 2015 16:47:54 +0100 Subject: [PATCH 10/66] Minor rename. Report errors properly. --- alethzero/MainWin.cpp | 4 ++-- eth/main.cpp | 25 ++++++++++++++----------- libdevcore/CommonData.cpp | 6 +++--- libdevcore/CommonData.h | 8 ++++---- neth/main.cpp | 10 +++++----- test/TestHelper.cpp | 2 +- 6 files changed, 29 insertions(+), 26 deletions(-) diff --git a/alethzero/MainWin.cpp b/alethzero/MainWin.cpp index 967bc6b56..0d440089b 100644 --- a/alethzero/MainWin.cpp +++ b/alethzero/MainWin.cpp @@ -583,7 +583,7 @@ Address Main::fromString(QString const& _n) const { try { - return Address(fromHex(_n.toStdString(), ThrowType::Throw)); + return Address(fromHex(_n.toStdString(), WhenError::Throw)); } catch (BadHexCharacter& _e) { @@ -1388,7 +1388,7 @@ void Main::on_inject_triggered() QString s = QInputDialog::getText(this, "Inject Transaction", "Enter transaction dump in hex"); try { - bytes b = fromHex(s.toStdString(), ThrowType::Throw); + bytes b = fromHex(s.toStdString(), WhenError::Throw); ethereum()->inject(&b); } catch (BadHexCharacter& _e) diff --git a/eth/main.cpp b/eth/main.cpp index 81e910716..88eb206b2 100644 --- a/eth/main.cpp +++ b/eth/main.cpp @@ -273,10 +273,9 @@ int main(int argc, char** argv) else if ((arg == "-c" || arg == "--client-name") && i + 1 < argc) clientName = argv[++i]; else if ((arg == "-a" || arg == "--address" || arg == "--coinbase-address") && i + 1 < argc) - { try { - coinbase = h160(fromHex(argv[++i], ThrowType::Throw)); + coinbase = h160(fromHex(argv[++i], WhenError::Throw)); } catch (BadHexCharacter& _e) { @@ -289,7 +288,6 @@ int main(int argc, char** argv) cwarn << "coinbase rejected"; break; } - } else if ((arg == "-s" || arg == "--secret") && i + 1 < argc) us = KeyPair(h256(fromHex(argv[++i]))); else if (arg == "--structured-logging-format" && i + 1 < argc) @@ -300,20 +298,24 @@ int main(int argc, char** argv) dbPath = argv[++i]; else if ((arg == "-B" || arg == "--block-fees") && i + 1 < argc) { - try { + try + { blockFees = stof(argv[++i]); } - catch (...) { + catch (...) + { cerr << "Bad " << arg << " option: " << argv[++i] << endl; return -1; } } else if ((arg == "-e" || arg == "--ether-price") && i + 1 < argc) { - try { + try + { etherPrice = stof(argv[++i]); } - catch (...) { + catch (...) + { cerr << "Bad " << arg << " option: " << argv[++i] << endl; return -1; } @@ -434,7 +436,8 @@ int main(int argc, char** argv) c->setAddress(coinbase); } - cout << "Address: " << endl << toHex(us.address().asArray()) << endl; + cout << "Transaction Signer: " << us.address() << endl; + cout << "Mining Benefactor: " << coinbase << endl; web3.startNetwork(); if (bootstrap) @@ -720,7 +723,7 @@ int main(int argc, char** argv) u256 minGas = (u256)Client::txGas(bytes(), 0); try { - Address dest = h160(fromHex(hexAddr, ThrowType::Throw)); + Address dest = h160(fromHex(hexAddr, WhenError::Throw)); c->submitTransaction(us.secret(), amount, dest, bytes(), minGas); } catch (BadHexCharacter& _e) @@ -764,7 +767,7 @@ int main(int argc, char** argv) stringstream ssc; try { - init = fromHex(sinit, ThrowType::Throw); + init = fromHex(sinit, WhenError::Throw); } catch (BadHexCharacter& _e) { @@ -925,7 +928,7 @@ int main(int argc, char** argv) { try { - coinbase = h160(fromHex(hexAddr, ThrowType::Throw)); + coinbase = h160(fromHex(hexAddr, WhenError::Throw)); } catch (BadHexCharacter& _e) { diff --git a/libdevcore/CommonData.cpp b/libdevcore/CommonData.cpp index 17e393cbe..6cad29952 100644 --- a/libdevcore/CommonData.cpp +++ b/libdevcore/CommonData.cpp @@ -78,7 +78,7 @@ int dev::fromHex(char _i) BOOST_THROW_EXCEPTION(BadHexCharacter() << errinfo_invalidSymbol(_i)); } -bytes dev::fromHex(std::string const& _s, ThrowType _throw) +bytes dev::fromHex(std::string const& _s, WhenError _throw) { unsigned s = (_s[0] == '0' && _s[1] == 'x') ? 2 : 0; std::vector ret; @@ -96,7 +96,7 @@ bytes dev::fromHex(std::string const& _s, ThrowType _throw) #ifndef BOOST_NO_EXCEPTIONS cwarn << boost::current_exception_diagnostic_information(); #endif - if (_throw == ThrowType::Throw) + if (_throw == WhenError::Throw) throw; } for (unsigned i = s; i < _s.size(); i += 2) @@ -109,7 +109,7 @@ bytes dev::fromHex(std::string const& _s, ThrowType _throw) #ifndef BOOST_NO_EXCEPTIONS cwarn << boost::current_exception_diagnostic_information(); #endif - if (_throw == ThrowType::Throw) + if (_throw == WhenError::Throw) throw; } return ret; diff --git a/libdevcore/CommonData.h b/libdevcore/CommonData.h index 2c9fd30ef..1c7a4cd61 100644 --- a/libdevcore/CommonData.h +++ b/libdevcore/CommonData.h @@ -35,9 +35,9 @@ namespace dev // String conversion functions, mainly to/from hex/nibble/byte representations. -enum class ThrowType +enum class WhenError { - NoThrow = 0, + DontThrow = 0, Throw = 1, }; @@ -59,8 +59,8 @@ int fromHex(char _i); /// Converts a (printable) ASCII hex string into the corresponding byte stream. /// @example fromHex("41626261") == asBytes("Abba") -/// If _throw = ThrowType::NoThrow, it replaces bad hex characters with 0's, otherwise it will throw an exception. -bytes fromHex(std::string const& _s, ThrowType _throw = ThrowType::NoThrow); +/// If _throw = ThrowType::DontThrow, it replaces bad hex characters with 0's, otherwise it will throw an exception. +bytes fromHex(std::string const& _s, WhenError _throw = WhenError::DontThrow); #if 0 std::string toBase58(bytesConstRef _data); diff --git a/neth/main.cpp b/neth/main.cpp index 2ce9872ca..5fa48dd7f 100644 --- a/neth/main.cpp +++ b/neth/main.cpp @@ -373,7 +373,7 @@ int main(int argc, char** argv) { try { - coinbase = h160(fromHex(argv[++i], ThrowType::Throw)); + coinbase = h160(fromHex(argv[++i], WhenError::Throw)); } catch (BadHexCharacter& _e) { @@ -734,8 +734,8 @@ int main(int argc, char** argv) { try { - Secret secret = h256(fromHex(sechex, ThrowType::Throw)); - Address dest = h160(fromHex(fields[0], ThrowType::Throw)); + Secret secret = h256(fromHex(sechex, WhenError::Throw)); + Address dest = h160(fromHex(fields[0], WhenError::Throw)); c->submitTransaction(secret, amount, dest, data, gas, gasPrice); } catch (BadHexCharacter& _e) @@ -786,7 +786,7 @@ int main(int argc, char** argv) u256 minGas = (u256)Client::txGas(bytes(), 0); try { - Address dest = h160(fromHex(fields[0], ThrowType::Throw)); + Address dest = h160(fromHex(fields[0], WhenError::Throw)); c->submitTransaction(us.secret(), amount, dest, bytes(), minGas); } catch (BadHexCharacter& _e) @@ -852,7 +852,7 @@ int main(int argc, char** argv) stringstream ssc; try { - init = fromHex(sinit, ThrowType::Throw); + init = fromHex(sinit, WhenError::Throw); } catch (BadHexCharacter& _e) { diff --git a/test/TestHelper.cpp b/test/TestHelper.cpp index 128318b8c..b29c5dc3a 100644 --- a/test/TestHelper.cpp +++ b/test/TestHelper.cpp @@ -240,7 +240,7 @@ byte toByte(json_spirit::mValue const& _v) bytes importByteArray(std::string const& _str) { - return fromHex(_str.substr(0, 2) == "0x" ? _str.substr(2) : _str, ThrowType::Throw); + return fromHex(_str.substr(0, 2) == "0x" ? _str.substr(2) : _str, WhenError::Throw); } bytes importData(json_spirit::mObject& _o) From e3cbc93f97a5b62dfa06dcf0f1b49563ecdc599c Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Fri, 20 Mar 2015 19:01:33 +0100 Subject: [PATCH 11/66] Auto gas requirement estimation for contract creation in AZ. --- alethzero/Transact.cpp | 60 +++++++++++++++++++++++++++++++++++++++--- alethzero/Transact.h | 13 ++++----- 2 files changed, 63 insertions(+), 10 deletions(-) diff --git a/alethzero/Transact.cpp b/alethzero/Transact.cpp index d89b2ef3c..b2614cedf 100644 --- a/alethzero/Transact.cpp +++ b/alethzero/Transact.cpp @@ -165,6 +165,8 @@ void Transact::on_destination_currentTextChanged(QString) void Transact::rejigData() { + if (!ethereum()) + return; if (isCreation()) { string src = ui->data->toPlainText().toStdString(); @@ -226,19 +228,61 @@ void Transact::rejigData() } } QString errs; + qint64 gasNeeded = 0; if (errors.size()) { errs = "

Errors

"; for (auto const& i: errors) errs.append("
" + QString::fromStdString(i).toHtmlEscaped() + "
"); } + else + { + if (true) + { + auto s = findSecret(value() + ethereum()->gasLimitRemaining() * gasPrice()); + if (!s) + errs += "
ERROR No single account contains enough gas.
"; + // TODO: use account with most balance anyway. + else + { + ExecutionResult er = ethereum()->create(s, value(), m_data, ethereum()->gasLimitRemaining(), gasPrice()); + gasNeeded = (qint64)er.gasUsed; + + if (er.excepted != TransactionException::None) + { + string exErr; + switch (er.excepted) + { + case TransactionException::Unknown: exErr = "Unknown error"; break; + case TransactionException::InvalidSignature: exErr = "Permanent Abort: Invalid transaction signature"; break; + case TransactionException::InvalidNonce: exErr = "Transient Abort: Invalid transaction nonce"; break; + case TransactionException::NotEnoughCash: exErr = "Transient Abort: Not enough cash to pay for transaction"; break; + case TransactionException::OutOfGasBase: exErr = "Permanent Abort: Not enough gas to consider transaction"; break; + case TransactionException::BlockGasLimitReached: exErr = "Transient Abort: Gas limit of block reached"; break; + case TransactionException::BadInstruction: exErr = "VM Error: Attempt to execute invalid instruction"; break; + case TransactionException::BadJumpDestination: exErr = "VM Error: Attempt to jump to invalid destination"; break; + case TransactionException::OutOfGas: exErr = "VM Error: Out of gas"; break; + case TransactionException::StackUnderflow: exErr = "VM Error: Stack underflow"; break; + default:; + } + errs += "
ERROR " + QString::fromStdString(exErr) + "ERROR Code deposit failed due to insufficient gas
"; + } + } + else + gasNeeded = (qint64)Interface::txGas(m_data, 0); + } + ui->code->setHtml(errs + lll + solidity + "

Code

" + QString::fromStdString(disassemble(m_data)).toHtmlEscaped() + "

Hex

" Div(Mono) + QString::fromStdString(toHex(m_data)) + ""); - ui->gas->setMinimum((qint64)Interface::txGas(m_data, 0)); + + ui->gas->setMinimum(gasNeeded); if (!ui->gas->isEnabled()) ui->gas->setValue(m_backupGas); ui->gas->setEnabled(true); - if (ui->gas->value() == ui->gas->minimum() && !src.empty()) - ui->gas->setValue((int)(m_ethereum->postState().gasLimitRemaining() / 10)); +// if (ui->gas->value() == ui->gas->minimum() && !src.empty()) +// ui->gas->setValue((int)(m_ethereum->postState().gasLimitRemaining() / 10)); } else { @@ -273,6 +317,15 @@ void Transact::rejigData() updateFee(); } +Secret Transact::findSecret(u256 _totalReq) const +{ + if (ethereum()) + for (auto const& i: m_myKeys) + if (ethereum()->balanceAt(i.address(), 0) >= _totalReq) + return i.secret(); + return Secret(); +} + void Transact::on_send_clicked() { u256 totalReq = value() + fee(); @@ -284,7 +337,6 @@ void Transact::on_send_clicked() { // If execution is a contract creation, add Natspec to // a local Natspec LEVELDB - ExecutionResult er = ethereum()->create(s, value(), m_data, ui->gas->value(), gasPrice()); ethereum()->submitTransaction(s, value(), m_data, ui->gas->value(), gasPrice()); string src = ui->data->toPlainText().toStdString(); if (sourceIsSolidity(src)) diff --git a/alethzero/Transact.h b/alethzero/Transact.h index 8ef4f41e0..b3702a6ae 100644 --- a/alethzero/Transact.h +++ b/alethzero/Transact.h @@ -57,7 +57,7 @@ private slots: void on_cancel_clicked() { close(); } private: - dev::eth::Client* ethereum() { return m_ethereum; } + dev::eth::Client* ethereum() const { return m_ethereum; } void rejigData(); void updateDestination(); @@ -69,14 +69,15 @@ private: dev::u256 gasPrice() const; std::string getFunctionHashes(dev::solidity::CompilerStack const& _compiler, std::string const& _contractName = std::string()); + dev::Secret findSecret(dev::u256 _totalReq) const; - Ui::Transact* ui; + Ui::Transact* ui = nullptr; - unsigned m_backupGas; + unsigned m_backupGas = 0; dev::bytes m_data; QList m_myKeys; - dev::eth::Client* m_ethereum; - Context* m_context; - NatSpecFace* m_natSpecDB; + dev::eth::Client* m_ethereum = nullptr; + Context* m_context = nullptr; + NatSpecFace* m_natSpecDB = nullptr; }; From 15f236282a99097f70e3db871c9742c96d190140 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Sat, 21 Mar 2015 11:56:13 +0100 Subject: [PATCH 12/66] Stack limit. --- libethcore/Params.cpp | 1 + libethcore/Params.h | 1 + libethereum/Transaction.cpp | 2 ++ libethereum/Transaction.h | 1 + libevm/VM.cpp | 36 ++++++++++++++++++++++++++++++++++++ libevm/VMFace.h | 1 + 6 files changed, 42 insertions(+) diff --git a/libethcore/Params.cpp b/libethcore/Params.cpp index d58888ab7..d70443fd9 100644 --- a/libethcore/Params.cpp +++ b/libethcore/Params.cpp @@ -37,6 +37,7 @@ u256 const c_gasLimitBoundDivisor = 1024; u256 const c_minimumDifficulty = 131072; u256 const c_difficultyBoundDivisor = 2048; u256 const c_durationLimit = 8; +u256 const c_stackLimit = 1024; u256 const c_tierStepGas[] = {0, 2, 3, 5, 8, 10, 20, 0}; u256 const c_expGas = 10; u256 const c_expByteGas = 10; diff --git a/libethcore/Params.h b/libethcore/Params.h index cab1852fa..7520e49f1 100644 --- a/libethcore/Params.h +++ b/libethcore/Params.h @@ -38,6 +38,7 @@ extern u256 const c_gasLimitBoundDivisor; extern u256 const c_minimumDifficulty; extern u256 const c_difficultyBoundDivisor; extern u256 const c_durationLimit; +extern u256 const c_stackLimit; extern u256 const c_tierStepGas[8]; ///< Once per operation, for a selection of them. extern u256 const c_expGas; ///< Once per EXP instuction. diff --git a/libethereum/Transaction.cpp b/libethereum/Transaction.cpp index 3a092bf25..31a7f74a9 100644 --- a/libethereum/Transaction.cpp +++ b/libethereum/Transaction.cpp @@ -46,6 +46,8 @@ TransactionException dev::eth::toTransactionException(VMException const& _e) return TransactionException::BadJumpDestination; if (!!dynamic_cast(&_e)) return TransactionException::OutOfGas; + if (!!dynamic_cast(&_e)) + return TransactionException::OutOfStack; if (!!dynamic_cast(&_e)) return TransactionException::StackUnderflow; return TransactionException::Unknown; diff --git a/libethereum/Transaction.h b/libethereum/Transaction.h index 8cb6cb7fc..561ec6269 100644 --- a/libethereum/Transaction.h +++ b/libethereum/Transaction.h @@ -56,6 +56,7 @@ enum class TransactionException BadInstruction, BadJumpDestination, OutOfGas, ///< Ran out of gas executing code of the transaction. + OutOfStack, ///< Ran out of stack executing code of the transaction. StackUnderflow }; diff --git a/libevm/VM.cpp b/libevm/VM.cpp index 6f6e08d4c..5738b8bdf 100644 --- a/libevm/VM.cpp +++ b/libevm/VM.cpp @@ -52,6 +52,8 @@ static array metrics() bytesConstRef VM::go(ExtVMFace& _ext, OnOpFunc const& _onOp, uint64_t _steps) { + m_stack.reserve((unsigned)c_stackLimit); + static const array c_metrics = metrics(); auto memNeed = [](u256 _offset, dev::u256 _size) { return _size ? (bigint)_offset + _size : (bigint)0; }; @@ -183,6 +185,40 @@ bytesConstRef VM::go(ExtVMFace& _ext, OnOpFunc const& _onOp, uint64_t _steps) runGas = c_expGas + c_expByteGas * (32 - (h256(expon).firstBitSet() / 8)); break; } + case Instruction::PUSH1: + case Instruction::PUSH2: + case Instruction::PUSH3: + case Instruction::PUSH4: + case Instruction::PUSH5: + case Instruction::PUSH6: + case Instruction::PUSH7: + case Instruction::PUSH8: + case Instruction::PUSH9: + case Instruction::PUSH10: + case Instruction::PUSH11: + case Instruction::PUSH12: + case Instruction::PUSH13: + case Instruction::PUSH14: + case Instruction::PUSH15: + case Instruction::PUSH16: + case Instruction::PUSH17: + case Instruction::PUSH18: + case Instruction::PUSH19: + case Instruction::PUSH20: + case Instruction::PUSH21: + case Instruction::PUSH22: + case Instruction::PUSH23: + case Instruction::PUSH24: + case Instruction::PUSH25: + case Instruction::PUSH26: + case Instruction::PUSH27: + case Instruction::PUSH28: + case Instruction::PUSH29: + case Instruction::PUSH30: + case Instruction::PUSH31: + case Instruction::PUSH32: + if (m_stack.size() > c_stackLimit) + BOOST_THROW_EXCEPTION(OutOfStack()); default:; } diff --git a/libevm/VMFace.h b/libevm/VMFace.h index 7b99b5bfd..d2689d13e 100644 --- a/libevm/VMFace.h +++ b/libevm/VMFace.h @@ -31,6 +31,7 @@ struct BreakPointHit: virtual VMException {}; struct BadInstruction: virtual VMException {}; struct BadJumpDestination: virtual VMException {}; struct OutOfGas: virtual VMException {}; +struct OutOfStack: virtual VMException {}; struct StackUnderflow: virtual VMException {}; /// EVM Virtual Machine interface From 64922cb150b27eb04f32c69420eec3b0741f7bf2 Mon Sep 17 00:00:00 2001 From: CJentzsch Date: Sat, 21 Mar 2015 12:02:59 +0100 Subject: [PATCH 13/66] max stack limit test --- test/stMemoryStressTestFiller.json | 44 ++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/test/stMemoryStressTestFiller.json b/test/stMemoryStressTestFiller.json index d697db44e..9fff9c0a4 100644 --- a/test/stMemoryStressTestFiller.json +++ b/test/stMemoryStressTestFiller.json @@ -167,5 +167,49 @@ "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", "data" : "" } + }, + + "FillStack" : { + "env" : { + "currentCoinbase" : "945304eb96065b2a98b57a48a06ae28d285a71b5", + "currentDifficulty" : "5623894562375", + "currentGasLimit" : "115792089237316195423570985008687907853269984665640564039457584007913129639935", + "currentNumber" : "0", + "currentTimestamp" : "1", + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "0", + "code" : "0x5b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe457f00000000000000000000000100000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000017f000000000000000000000000000000000000000000000000000000000000c3504357155320803a975560005155", + "nonce" : "0", + "storage" : { + } + }, + "945304eb96065b2a98b57a48a06ae28d285a71b5" : { + "balance" : "46", + "code" : "0x6000355415600957005b60203560003555", + "nonce" : "0", + "storage" : { + } + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "1000000000000000000", + "code" : "0x", + "nonce" : "0", + "storage" : { + } + } + }, + "transaction" : { + "data" : "0x5b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe457f00000000000000000000000100000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000017f000000000000000000000000000000000000000000000000000000000000c3504357155320803a97", + "gasLimit" : "3141592", + "gasPrice" : "1", + "nonce" : "0", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "264050067" + } } + } From b76c5950dcc93c219eb6944c15f996cb2b04fca8 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Sat, 21 Mar 2015 12:21:06 +0100 Subject: [PATCH 14/66] Rookie erros fixed. --- libevm/VM.cpp | 38 +++----------------------------------- libevm/VM.h | 2 +- 2 files changed, 4 insertions(+), 36 deletions(-) diff --git a/libevm/VM.cpp b/libevm/VM.cpp index 5738b8bdf..2c1627db9 100644 --- a/libevm/VM.cpp +++ b/libevm/VM.cpp @@ -36,6 +36,7 @@ struct InstructionMetric { int gasPriceTier; int args; + int ret; }; static array metrics() @@ -46,6 +47,7 @@ static array metrics() InstructionInfo inst = instructionInfo((Instruction)i); s_ret[i].gasPriceTier = inst.gasPriceTier; s_ret[i].args = inst.args; + s_ret[i].ret = inst.ret; } return s_ret; } @@ -91,7 +93,7 @@ bytesConstRef VM::go(ExtVMFace& _ext, OnOpFunc const& _onOp, uint64_t _steps) // should work, but just seems to result in immediate errorless exit on initial execution. yeah. weird. //m_onFail = std::function(onOperation); - require(metric.args); + require(metric.args, metric.ret); auto onOperation = [&]() { @@ -185,40 +187,6 @@ bytesConstRef VM::go(ExtVMFace& _ext, OnOpFunc const& _onOp, uint64_t _steps) runGas = c_expGas + c_expByteGas * (32 - (h256(expon).firstBitSet() / 8)); break; } - case Instruction::PUSH1: - case Instruction::PUSH2: - case Instruction::PUSH3: - case Instruction::PUSH4: - case Instruction::PUSH5: - case Instruction::PUSH6: - case Instruction::PUSH7: - case Instruction::PUSH8: - case Instruction::PUSH9: - case Instruction::PUSH10: - case Instruction::PUSH11: - case Instruction::PUSH12: - case Instruction::PUSH13: - case Instruction::PUSH14: - case Instruction::PUSH15: - case Instruction::PUSH16: - case Instruction::PUSH17: - case Instruction::PUSH18: - case Instruction::PUSH19: - case Instruction::PUSH20: - case Instruction::PUSH21: - case Instruction::PUSH22: - case Instruction::PUSH23: - case Instruction::PUSH24: - case Instruction::PUSH25: - case Instruction::PUSH26: - case Instruction::PUSH27: - case Instruction::PUSH28: - case Instruction::PUSH29: - case Instruction::PUSH30: - case Instruction::PUSH31: - case Instruction::PUSH32: - if (m_stack.size() > c_stackLimit) - BOOST_THROW_EXCEPTION(OutOfStack()); default:; } diff --git a/libevm/VM.h b/libevm/VM.h index 3efb3b119..b14a117df 100644 --- a/libevm/VM.h +++ b/libevm/VM.h @@ -56,7 +56,7 @@ public: virtual bytesConstRef go(ExtVMFace& _ext, OnOpFunc const& _onOp = {}, uint64_t _steps = (uint64_t)-1) override final; - void require(u256 _n) { if (m_stack.size() < _n) { if (m_onFail) m_onFail(); BOOST_THROW_EXCEPTION(StackUnderflow() << RequirementError((bigint)_n, (bigint)m_stack.size())); } } + void require(u256 _n, u256 _d) { if (m_stack.size() < _n) { if (m_onFail) m_onFail(); BOOST_THROW_EXCEPTION(StackUnderflow() << RequirementError((bigint)_n, (bigint)m_stack.size())); } if (m_stack.size() - _n + _d >= c_stackLimit) { if (m_onFail) m_onFail(); BOOST_THROW_EXCEPTION(OutOfStack() << RequirementError((bigint)(_d - _n), (bigint)m_stack.size())); } } void requireMem(unsigned _n) { if (m_temp.size() < _n) { m_temp.resize(_n); } } u256 curPC() const { return m_curPC; } From aadf3998d941be0f337dc3c29aa1e464283de5c2 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Sat, 21 Mar 2015 12:22:08 +0100 Subject: [PATCH 15/66] AZ transact auto-gas determination. --- alethzero/Transact.cpp | 89 ++++++++++++++++++++++++++++++------------ 1 file changed, 65 insertions(+), 24 deletions(-) diff --git a/alethzero/Transact.cpp b/alethzero/Transact.cpp index b2614cedf..30e069fd0 100644 --- a/alethzero/Transact.cpp +++ b/alethzero/Transact.cpp @@ -163,6 +163,25 @@ void Transact::on_destination_currentTextChanged(QString) // updateFee(); } +static std::string toString(TransactionException _te) +{ + switch (_te) + { + case TransactionException::Unknown: return "Unknown error"; + case TransactionException::InvalidSignature: return "Permanent Abort: Invalid transaction signature"; + case TransactionException::InvalidNonce: return "Transient Abort: Invalid transaction nonce"; + case TransactionException::NotEnoughCash: return "Transient Abort: Not enough cash to pay for transaction"; + case TransactionException::OutOfGasBase: return "Permanent Abort: Not enough gas to consider transaction"; + case TransactionException::BlockGasLimitReached: return "Transient Abort: Gas limit of block reached"; + case TransactionException::BadInstruction: return "VM Error: Attempt to execute invalid instruction"; + case TransactionException::BadJumpDestination: return "VM Error: Attempt to jump to invalid destination"; + case TransactionException::OutOfGas: return "VM Error: Out of gas"; + case TransactionException::OutOfStack: return "VM Error: VM stack limit reached during execution"; + case TransactionException::StackUnderflow: return "VM Error: Stack underflow"; + default:; return std::string(); + } +} + void Transact::rejigData() { if (!ethereum()) @@ -247,26 +266,11 @@ void Transact::rejigData() { ExecutionResult er = ethereum()->create(s, value(), m_data, ethereum()->gasLimitRemaining(), gasPrice()); gasNeeded = (qint64)er.gasUsed; + auto base = (qint64)Interface::txGas(m_data, 0); + errs += QString("
INFO Gas required: %1 base, %2 init
").arg(base).arg((qint64)er.gasUsed - base); if (er.excepted != TransactionException::None) - { - string exErr; - switch (er.excepted) - { - case TransactionException::Unknown: exErr = "Unknown error"; break; - case TransactionException::InvalidSignature: exErr = "Permanent Abort: Invalid transaction signature"; break; - case TransactionException::InvalidNonce: exErr = "Transient Abort: Invalid transaction nonce"; break; - case TransactionException::NotEnoughCash: exErr = "Transient Abort: Not enough cash to pay for transaction"; break; - case TransactionException::OutOfGasBase: exErr = "Permanent Abort: Not enough gas to consider transaction"; break; - case TransactionException::BlockGasLimitReached: exErr = "Transient Abort: Gas limit of block reached"; break; - case TransactionException::BadInstruction: exErr = "VM Error: Attempt to execute invalid instruction"; break; - case TransactionException::BadJumpDestination: exErr = "VM Error: Attempt to jump to invalid destination"; break; - case TransactionException::OutOfGas: exErr = "VM Error: Out of gas"; break; - case TransactionException::StackUnderflow: exErr = "VM Error: Stack underflow"; break; - default:; - } - errs += "
ERROR " + QString::fromStdString(exErr) + "ERROR " + QString::fromStdString(toString(er.excepted)) + "
"; if (er.codeDeposit == CodeDeposit::Failed) errs += "
ERROR Code deposit failed due to insufficient gas
"; } @@ -277,18 +281,26 @@ void Transact::rejigData() ui->code->setHtml(errs + lll + solidity + "

Code

" + QString::fromStdString(disassemble(m_data)).toHtmlEscaped() + "

Hex

" Div(Mono) + QString::fromStdString(toHex(m_data)) + ""); - ui->gas->setMinimum(gasNeeded); - if (!ui->gas->isEnabled()) - ui->gas->setValue(m_backupGas); + if (ui->gas->value() == ui->gas->minimum()) + { + ui->gas->setMinimum(gasNeeded); + ui->gas->setValue(gasNeeded); + } + else + ui->gas->setMinimum(gasNeeded); +// if (!ui->gas->isEnabled()) +// ui->gas->setValue(m_backupGas); ui->gas->setEnabled(true); // if (ui->gas->value() == ui->gas->minimum() && !src.empty()) // ui->gas->setValue((int)(m_ethereum->postState().gasLimitRemaining() / 10)); } else { + auto base = (qint64)Interface::txGas(m_data, 0); m_data = parseData(ui->data->toPlainText().toStdString()); auto to = m_context->fromString(ui->destination->currentText()); QString natspec; + QString errs; if (ethereum()->codeAt(to, 0).size()) { string userNotice = m_natSpecDB->getUserNotice(ethereum()->postState().codeHash(to), m_data); @@ -299,7 +311,35 @@ void Transact::rejigData() NatspecExpressionEvaluator evaluator; natspec = evaluator.evalExpression(QString::fromStdString(userNotice)); } - ui->gas->setMinimum((qint64)Interface::txGas(m_data, 1)); + + qint64 gasNeeded = 0; + if (true) + { + auto s = findSecret(value() + ethereum()->gasLimitRemaining() * gasPrice()); + if (!s) + errs += "
ERROR No single account contains enough gas.
"; + // TODO: use account with most balance anyway. + else + { + ExecutionResult er = ethereum()->call(s, value(), to, m_data, ethereum()->gasLimitRemaining(), gasPrice()); + gasNeeded = (qint64)er.gasUsed; + errs += QString("
INFO Gas required: %1 base, %2 exec
").arg(base).arg((qint64)er.gasUsed - base); + + if (er.excepted != TransactionException::None) + errs += "
ERROR " + QString::fromStdString(toString(er.excepted)) + "
"; + } + } + else + gasNeeded = (qint64)Interface::txGas(m_data, 0); + + if (ui->gas->value() == ui->gas->minimum()) + { + ui->gas->setMinimum(gasNeeded); + ui->gas->setValue(gasNeeded); + } + else + ui->gas->setMinimum(gasNeeded); + if (!ui->gas->isEnabled()) ui->gas->setValue(m_backupGas); ui->gas->setEnabled(true); @@ -309,10 +349,11 @@ void Transact::rejigData() natspec += "Destination not a contract."; if (ui->gas->isEnabled()) m_backupGas = ui->gas->value(); - ui->gas->setValue((qint64)Interface::txGas(m_data)); + ui->gas->setMinimum(base); + ui->gas->setValue(base); ui->gas->setEnabled(false); } - ui->code->setHtml("

NatSpec

" + natspec + "

Dump

" + QString::fromStdString(dev::memDump(m_data, 8, true)) + "

Hex

" + Div(Mono) + QString::fromStdString(toHex(m_data)) + ""); + ui->code->setHtml(errs + "

NatSpec

" + natspec + "

Dump

" + QString::fromStdString(dev::memDump(m_data, 8, true)) + "

Hex

" + Div(Mono) + QString::fromStdString(toHex(m_data)) + ""); } updateFee(); } From 793deb8f655a00e8e6d1be7e9ae15bdaa16e2850 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Sat, 21 Mar 2015 12:41:12 +0100 Subject: [PATCH 16/66] --kill-blockchain option in eth. Fixes #1367 --- eth/main.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/eth/main.cpp b/eth/main.cpp index 88eb206b2..55d64609e 100644 --- a/eth/main.cpp +++ b/eth/main.cpp @@ -119,6 +119,7 @@ void help() << " -j,--json-rpc Enable JSON-RPC server (default: off)." << endl << " --json-rpc-port Specify JSON-RPC server port (implies '-j', default: 8080)." << endl #endif + << " -K,--kill-blockchain First kill the blockchain." << endl << " -l,--listen Listen on the given port for incoming connected (default: 30303)." << endl << " -L,--local-networking Use peers whose addresses are local." << endl << " -m,--mining Enable mining, optionally for a specified number of blocks (Default: off)" << endl @@ -214,6 +215,7 @@ int main(int argc, char** argv) bool upnp = true; bool useLocal = false; bool forceMining = false; + bool killChain = false; bool jit = false; bool structuredLogging = false; string structuredLoggingFormat = "%Y-%m-%dT%H:%M:%S"; @@ -270,6 +272,8 @@ int main(int argc, char** argv) } else if (arg == "-L" || arg == "--local-networking") useLocal = true; + else if (arg == "-K" || arg == "--kill-blockchain") + killChain = true; else if ((arg == "-c" || arg == "--client-name") && i + 1 < argc) clientName = argv[++i]; else if ((arg == "-a" || arg == "--address" || arg == "--coinbase-address") && i + 1 < argc) @@ -419,7 +423,7 @@ int main(int argc, char** argv) dev::WebThreeDirect web3( clientImplString, dbPath, - false, + killChain, mode == NodeMode::Full ? set{"eth", "shh"} : set(), netPrefs, &nodesState, From 1f161895fd60f479554e04d4aa0d9188d9572b04 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Sat, 21 Mar 2015 12:47:43 +0100 Subject: [PATCH 17/66] Place ethash cache in a more clearly shared folder. --- libdevcrypto/FileSystem.cpp | 9 ++++++--- libdevcrypto/FileSystem.h | 2 +- libethcore/Ethasher.cpp | 4 ++-- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/libdevcrypto/FileSystem.cpp b/libdevcrypto/FileSystem.cpp index 81b23e886..ed054553d 100644 --- a/libdevcrypto/FileSystem.cpp +++ b/libdevcrypto/FileSystem.cpp @@ -32,12 +32,15 @@ using namespace std; using namespace dev; -std::string dev::getDataDir() +std::string dev::getDataDir(std::string _prefix) { + if (_prefix.empty()) + _prefix = "ethereum"; #ifdef _WIN32 + _prefix[0] = toupper(_prefix[0]); char path[1024] = ""; if (SHGetSpecialFolderPathA(NULL, path, CSIDL_APPDATA, true)) - return (boost::filesystem::path(path) / "Ethereum").string(); + return (boost::filesystem::path(path) / _prefix).string(); else { #ifndef _MSC_VER // todo? @@ -57,7 +60,7 @@ std::string dev::getDataDir() // This eventually needs to be put in proper wrapper (to support sandboxing) return (dataDirPath / "Library/Application Support/Ethereum").string(); #else - return (dataDirPath / ".ethereum").string(); + return (dataDirPath / ("." + _prefix)).string(); #endif #endif } diff --git a/libdevcrypto/FileSystem.h b/libdevcrypto/FileSystem.h index 281e60e24..6c8160a58 100644 --- a/libdevcrypto/FileSystem.h +++ b/libdevcrypto/FileSystem.h @@ -30,6 +30,6 @@ namespace dev { /// @returns the path for user data. -std::string getDataDir(); +std::string getDataDir(std::string _prefix = "ethereum"); } diff --git a/libethcore/Ethasher.cpp b/libethcore/Ethasher.cpp index 80c263673..44a555fde 100644 --- a/libethcore/Ethasher.cpp +++ b/libethcore/Ethasher.cpp @@ -71,10 +71,10 @@ bytesConstRef Ethasher::full(BlockInfo const& _header) m_fulls.erase(m_fulls.begin()); } try { - boost::filesystem::create_directories(getDataDir() + "/ethashcache"); + boost::filesystem::create_directories(getDataDir("ethash")); } catch (...) {} - std::string memoFile = getDataDir() + "/ethashcache/full"; + std::string memoFile = getDataDir("ethash") + "/full"; auto info = rlpList(c_ethashRevision, _header.seedHash()); if (boost::filesystem::exists(memoFile) && contents(memoFile + ".info") != info) boost::filesystem::remove(memoFile); From 73d889e9970a46d6840e06a862d3e9595c234486 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Sat, 21 Mar 2015 14:11:48 +0100 Subject: [PATCH 18/66] Filter niceties. --- alethzero/Transact.cpp | 60 +++++++++++------------ libethereum/Client.cpp | 12 ++--- libethereum/LogFilter.cpp | 27 ++++++++++ libethereum/LogFilter.h | 20 ++++++-- libweb3jsonrpc/WebThreeStubServerBase.cpp | 17 ++++++- 5 files changed, 92 insertions(+), 44 deletions(-) diff --git a/alethzero/Transact.cpp b/alethzero/Transact.cpp index 30e069fd0..4b7bea73f 100644 --- a/alethzero/Transact.cpp +++ b/alethzero/Transact.cpp @@ -369,39 +369,37 @@ Secret Transact::findSecret(u256 _totalReq) const void Transact::on_send_clicked() { - u256 totalReq = value() + fee(); - for (auto const& i: m_myKeys) - if (ethereum()->balanceAt(i.address(), 0) >= totalReq) - { - Secret s = i.secret(); - if (isCreation()) + Secret s = findSecret(value() + fee()); + if (!s) + { + QMessageBox::critical(this, "Transaction Failed", "Couldn't make transaction: no single account contains at least the required amount."); + return; + } + + if (isCreation()) + { + // If execution is a contract creation, add Natspec to + // a local Natspec LEVELDB + ethereum()->submitTransaction(s, value(), m_data, ui->gas->value(), gasPrice()); + string src = ui->data->toPlainText().toStdString(); + if (sourceIsSolidity(src)) + try { - // If execution is a contract creation, add Natspec to - // a local Natspec LEVELDB - ethereum()->submitTransaction(s, value(), m_data, ui->gas->value(), gasPrice()); - string src = ui->data->toPlainText().toStdString(); - if (sourceIsSolidity(src)) - try - { - dev::solidity::CompilerStack compiler(true); - m_data = compiler.compile(src, ui->optimize->isChecked()); - for (string const& s: compiler.getContractNames()) - { - h256 contractHash = compiler.getContractCodeHash(s); - m_natSpecDB->add(contractHash, compiler.getMetadata(s, dev::solidity::DocumentationType::NatspecUser)); - } - } - catch (...) - { - } - close(); - return; + dev::solidity::CompilerStack compiler(true); + m_data = compiler.compile(src, ui->optimize->isChecked()); + for (string const& s: compiler.getContractNames()) + { + h256 contractHash = compiler.getContractCodeHash(s); + m_natSpecDB->add(contractHash, compiler.getMetadata(s, dev::solidity::DocumentationType::NatspecUser)); + } } - else - ethereum()->submitTransaction(s, value(), m_context->fromString(ui->destination->currentText()), m_data, ui->gas->value(), gasPrice()); - return; - } - QMessageBox::critical(this, "Transaction Failed", "Couldn't make transaction: no single account contains at least the required amount."); + catch (...) + { + } + } + else + ethereum()->submitTransaction(s, value(), m_context->fromString(ui->destination->currentText()), m_data, ui->gas->value(), gasPrice()); + close(); } void Transact::on_debug_clicked() diff --git a/libethereum/Client.cpp b/libethereum/Client.cpp index fb29ffb6a..3ca06f381 100644 --- a/libethereum/Client.cpp +++ b/libethereum/Client.cpp @@ -357,11 +357,11 @@ LocalisedLogEntries Client::checkWatch(unsigned _watchId) return ret; } -void Client::appendFromNewPending(TransactionReceipt const& _receipt, h256Set& io_changed, h256 _sha3) +void Client::appendFromNewPending(TransactionReceipt const& _receipt, h256Set& io_changed, h256 _transactionHash) { Guard l(m_filterLock); for (pair& i: m_filters) - if ((unsigned)i.second.filter.latest() > m_bc.number()) + if (i.second.filter.envelops(RelativeBlock::Pending, m_bc.number() + 1)) { // acceptable number. auto m = i.second.filter.matches(_receipt); @@ -369,7 +369,7 @@ void Client::appendFromNewPending(TransactionReceipt const& _receipt, h256Set& i { // filter catches them for (LogEntry const& l: m) - i.second.changes.push_back(LocalisedLogEntry(l, m_bc.number() + 1, _sha3)); + i.second.changes.push_back(LocalisedLogEntry(l, m_bc.number() + 1, _transactionHash)); io_changed.insert(i.first); } } @@ -383,7 +383,7 @@ void Client::appendFromNewBlock(h256 const& _block, h256Set& io_changed) Guard l(m_filterLock); for (pair& i: m_filters) - if ((unsigned)i.second.filter.latest() >= d.number && (unsigned)i.second.filter.earliest() <= d.number && i.second.filter.matches(d.logBloom)) + if (i.second.filter.envelops(RelativeBlock::Latest, d.number) && i.second.filter.matches(d.logBloom)) // acceptable number & looks like block may contain a matching log entry. for (size_t j = 0; j < br.receipts.size(); j++) { @@ -391,10 +391,10 @@ void Client::appendFromNewBlock(h256 const& _block, h256Set& io_changed) auto m = i.second.filter.matches(tr); if (m.size()) { - auto sha3 = transaction(d.hash, j).sha3(); + auto transactionHash = transaction(d.hash, j).sha3(); // filter catches them for (LogEntry const& l: m) - i.second.changes.push_back(LocalisedLogEntry(l, (unsigned)d.number, sha3)); + i.second.changes.push_back(LocalisedLogEntry(l, (unsigned)d.number, transactionHash)); io_changed.insert(i.first); } } diff --git a/libethereum/LogFilter.cpp b/libethereum/LogFilter.cpp index 45716a949..a2a1aa40e 100644 --- a/libethereum/LogFilter.cpp +++ b/libethereum/LogFilter.cpp @@ -46,6 +46,33 @@ h256 LogFilter::sha3() const return dev::sha3(s.out()); } +static bool isNoLater(RelativeBlock _logBlockRelation, u256 _logBlockNumber, int _latest) +{ + if (_latest == PendingBlock) + return true; + else if (_latest == LatestBlock) + return _logBlockRelation == RelativeBlock::Latest; + else + return _logBlockNumber <= _latest; +} + +static bool isNoEarlier(RelativeBlock _logBlockRelation, u256 _logBlockNumber, int _earliest) +{ + if (_earliest == PendingBlock) + return _logBlockRelation == RelativeBlock::Pending; + else if (_earliest == LatestBlock) + return true; + else + return _logBlockNumber >= _earliest; +} + +bool LogFilter::envelops(RelativeBlock _logBlockRelation, u256 _logBlockNumber) const +{ + return + isNoLater(_logBlockRelation, _logBlockNumber, m_latest) && + isNoEarlier(_logBlockRelation, _logBlockNumber, m_earliest); +} + bool LogFilter::matches(LogBloom _bloom) const { if (m_addresses.size()) diff --git a/libethereum/LogFilter.h b/libethereum/LogFilter.h index a28bfe806..7b808a0eb 100644 --- a/libethereum/LogFilter.h +++ b/libethereum/LogFilter.h @@ -42,17 +42,27 @@ std::ostream& operator<<(std::ostream& _out, dev::eth::LogFilter const& _s); class State; +enum class RelativeBlock +{ + Latest, + Pending +}; + +static const unsigned LatestBlock = (unsigned)-2; +static const unsigned PendingBlock = (unsigned)-1; + class LogFilter { public: - LogFilter(int _earliest = 0, int _latest = -1): m_earliest(_earliest), m_latest(_latest) {} + LogFilter(unsigned _earliest = 0, unsigned _latest = PendingBlock): m_earliest(_earliest), m_latest(_latest) {} void streamRLP(RLPStream& _s) const; h256 sha3() const; - int earliest() const { return m_earliest; } - int latest() const { return m_latest; } + unsigned earliest() const { return m_earliest; } + unsigned latest() const { return m_latest; } + bool envelops(RelativeBlock _logBlockRelation, u256 _logBlockNumber) const; std::vector bloomPossibilities() const; bool matches(LogBloom _bloom) const; bool matches(State const& _s, unsigned _i) const; @@ -68,8 +78,8 @@ public: private: AddressSet m_addresses; std::array m_topics; - int m_earliest = 0; - int m_latest = -1; + unsigned m_earliest = 0; + unsigned m_latest = LatestBlock; }; } diff --git a/libweb3jsonrpc/WebThreeStubServerBase.cpp b/libweb3jsonrpc/WebThreeStubServerBase.cpp index 6424354f2..1bbd8b404 100644 --- a/libweb3jsonrpc/WebThreeStubServerBase.cpp +++ b/libweb3jsonrpc/WebThreeStubServerBase.cpp @@ -139,6 +139,18 @@ static Json::Value toJson(map const& _storage) return res; } +static unsigned jsToBlockIndex(std::string const& _js) +{ + if (_js == "latest") + return LatestBlock; + else if (_js == "earliest") + return 0; + else if (_js == "pending") + return PendingBlock; + else + return (unsigned)jsToInt(_js); +} + static dev::eth::LogFilter toLogFilter(Json::Value const& _json) // commented to avoid warning. Uncomment once in use @ PoC-7. { dev::eth::LogFilter filter; @@ -147,9 +159,9 @@ static dev::eth::LogFilter toLogFilter(Json::Value const& _json) // commented to // check only !empty. it should throw exceptions if input params are incorrect if (!_json["fromBlock"].empty()) - filter.withEarliest(jsToInt(_json["fromBlock"].asString())); + filter.withEarliest(jsToBlockIndex(_json["fromBlock"].asString())); if (!_json["toBlock"].empty()) - filter.withLatest(jsToInt(_json["toBlock"].asString())); + filter.withLatest(jsToBlockIndex(_json["toBlock"].asString())); if (!_json["address"].empty()) { if (_json["address"].isArray()) @@ -227,6 +239,7 @@ static Json::Value toJson(h256 const& _h, shh::Envelope const& _e, shh::Message return res; } +// TODO: convert to jsToBlockNumber, downstream. too. static int toBlockNumber(string const& _string) { if (_string.compare("latest") == 0) From e57d6ae6336689b1d906275da8e28677b2538030 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Sat, 21 Mar 2015 18:57:34 +0100 Subject: [PATCH 19/66] Unify block numbers into BlockNumber type. Uniformally handle 'latest' & 'pending'. --- alethzero/MainWin.cpp | 12 ++++++------ alethzero/Transact.cpp | 4 ++-- eth/main.cpp | 8 ++++---- libethcore/Common.h | 11 +++++++++++ libethereum/Client.cpp | 24 +++++++++++------------ libethereum/Client.h | 21 ++++++++++---------- libethereum/Interface.h | 22 ++++++++++----------- libethereum/LogFilter.cpp | 4 ++-- libethereum/LogFilter.h | 9 --------- libweb3jsonrpc/WebThreeStubServerBase.cpp | 16 +++------------ mix/MixClient.cpp | 18 ++++++++--------- mix/MixClient.h | 19 +++++++++--------- neth/main.cpp | 12 ++++++------ third/MainWin.cpp | 20 +++++++++---------- 14 files changed, 97 insertions(+), 103 deletions(-) diff --git a/alethzero/MainWin.cpp b/alethzero/MainWin.cpp index 0d440089b..d99626ff0 100644 --- a/alethzero/MainWin.cpp +++ b/alethzero/MainWin.cpp @@ -312,7 +312,7 @@ void Main::installBalancesWatch() Address coinsAddr = getCurrencies(); // TODO: Update for new currencies reg. - for (unsigned i = 0; i < ethereum()->stateAt(coinsAddr, 0); ++i) + for (unsigned i = 0; i < ethereum()->stateAt(coinsAddr, PendingBlock); ++i) altCoins.push_back(right160(ethereum()->stateAt(coinsAddr, i + 1))); for (auto i: m_myKeys) for (auto c: altCoins) @@ -616,10 +616,10 @@ QString Main::lookup(QString const& _a) const h256 ret; // TODO: fix with the new DNSreg contract -// if (h160 dnsReg = (u160)ethereum()->stateAt(c_config, 4, 0)) +// if (h160 dnsReg = (u160)ethereum()->stateAt(c_config, 4, PendingBlock)) // ret = ethereum()->stateAt(dnsReg, n); /* if (!ret) - if (h160 nameReg = (u160)ethereum()->stateAt(c_config, 0, 0)) + if (h160 nameReg = (u160)ethereum()->stateAt(c_config, 0, PendingBlock)) ret = ethereum()->stateAt(nameReg, n2); */ if (ret && !((u256)ret >> 32)) @@ -937,7 +937,7 @@ void Main::refreshBalances() u256 totalBalance = 0; /* map> altCoins; Address coinsAddr = getCurrencies(); - for (unsigned i = 0; i < ethereum()->stateAt(coinsAddr, 0); ++i) + for (unsigned i = 0; i < ethereum()->stateAt(coinsAddr, PendingBlock); ++i) { auto n = ethereum()->stateAt(coinsAddr, i + 1); auto addr = right160(ethereum()->stateAt(coinsAddr, n)); @@ -1357,7 +1357,7 @@ void Main::on_transactionQueue_currentItemChanged() auto r = receipt.rlp(); s << "
Receipt: " << toString(RLP(r)) << "
"; s << "
Receipt-Hex: " Span(Mono) << toHex(receipt.rlp()) << "
"; - s << renderDiff(ethereum()->diff(i, 0)); + s << renderDiff(ethereum()->diff(i, PendingBlock)); // s << "Pre: " << fs.rootHash() << "
"; // s << "Post: " << ts.rootHash() << ""; } @@ -1550,7 +1550,7 @@ void Main::on_debugCurrent_triggered() unsigned txi = item->data(Qt::UserRole + 1).toInt(); bytes t = ethereum()->blockChain().transaction(h, txi); State s(ethereum()->state(txi, h)); - Executive e(s, ethereum()->blockChain(), 0); + Executive e(s, ethereum()->blockChain(), PendingBlock); Debugger dw(this, this); dw.populate(e, Transaction(t, CheckSignature::Sender)); dw.exec(); diff --git a/alethzero/Transact.cpp b/alethzero/Transact.cpp index 4b7bea73f..35a9c47d2 100644 --- a/alethzero/Transact.cpp +++ b/alethzero/Transact.cpp @@ -301,7 +301,7 @@ void Transact::rejigData() auto to = m_context->fromString(ui->destination->currentText()); QString natspec; QString errs; - if (ethereum()->codeAt(to, 0).size()) + if (ethereum()->codeAt(to, PendingBlock).size()) { string userNotice = m_natSpecDB->getUserNotice(ethereum()->postState().codeHash(to), m_data); if (userNotice.empty()) @@ -362,7 +362,7 @@ Secret Transact::findSecret(u256 _totalReq) const { if (ethereum()) for (auto const& i: m_myKeys) - if (ethereum()->balanceAt(i.address(), 0) >= _totalReq) + if (ethereum()->balanceAt(i.address(), PendingBlock) >= _totalReq) return i.secret(); return Secret(); } diff --git a/eth/main.cpp b/eth/main.cpp index 55d64609e..f951f5a3c 100644 --- a/eth/main.cpp +++ b/eth/main.cpp @@ -687,7 +687,7 @@ int main(int argc, char** argv) auto acs =c->addresses(); string ss; for (auto const& i: acs) - if ( c->codeAt(i, 0).size()) + if ( c->codeAt(i, PendingBlock).size()) { ss = toString(i) + " : " + toString( c->balanceAt(i)) + " [" + toString((unsigned) c->countAt(i)) + "]"; cout << ss << endl; @@ -698,7 +698,7 @@ int main(int argc, char** argv) auto acs =c->addresses(); string ss; for (auto const& i: acs) - if ( c->codeAt(i, 0).empty()) + if ( c->codeAt(i, PendingBlock).empty()) { ss = toString(i) + " : " + toString( c->balanceAt(i)) + " [" + toString((unsigned) c->countAt(i)) + "]"; cout << ss << endl; @@ -890,10 +890,10 @@ int main(int argc, char** argv) try { - auto storage =c->storageAt(h, 0); + auto storage =c->storageAt(h, PendingBlock); for (auto const& i: storage) s << "@" << showbase << hex << i.first << " " << showbase << hex << i.second << endl; - s << endl << disassemble( c->codeAt(h, 0)) << endl; + s << endl << disassemble( c->codeAt(h, PendingBlock)) << endl; string outFile = getDataDir() + "/" + rechex + ".evm"; ofstream ofs; diff --git a/libethcore/Common.h b/libethcore/Common.h index aabb59d25..51322dcb2 100644 --- a/libethcore/Common.h +++ b/libethcore/Common.h @@ -71,5 +71,16 @@ static const u256 wei = exp10<0>(); using Nonce = h64; +using BlockNumber = unsigned; + +static const BlockNumber LatestBlock = (BlockNumber)-2; +static const BlockNumber PendingBlock = (BlockNumber)-1; + +enum class RelativeBlock: BlockNumber +{ + Latest = LatestBlock, + Pending = PendingBlock +}; + } } diff --git a/libethereum/Client.cpp b/libethereum/Client.cpp index 3ca06f381..6725d1560 100644 --- a/libethereum/Client.cpp +++ b/libethereum/Client.cpp @@ -491,7 +491,7 @@ void Client::submitTransaction(Secret _secret, u256 _value, Address _dest, bytes m_tq.attemptImport(t.rlp()); } -ExecutionResult Client::call(Secret _secret, u256 _value, Address _dest, bytes const& _data, u256 _gas, u256 _gasPrice, int _blockNumber) +ExecutionResult Client::call(Secret _secret, u256 _value, Address _dest, bytes const& _data, u256 _gas, u256 _gasPrice, BlockNumber _blockNumber) { ExecutionResult ret; try @@ -514,7 +514,7 @@ ExecutionResult Client::call(Secret _secret, u256 _value, Address _dest, bytes c return ret; } -ExecutionResult Client::create(Secret _secret, u256 _value, bytes const& _data, u256 _gas, u256 _gasPrice, int _blockNumber) +ExecutionResult Client::create(Secret _secret, u256 _value, bytes const& _data, u256 _gas, u256 _gasPrice, BlockNumber _blockNumber) { ExecutionResult ret; try @@ -739,12 +739,12 @@ unsigned Client::numberOf(int _n) const return m_bc.details().number + max(-(int)m_bc.details().number, 1 + _n); } -State Client::asOf(int _h) const +State Client::asOf(unsigned _h) const { ReadGuard l(x_stateDB); - if (_h == 0) + if (_h == PendingBlock) return m_postMine; - else if (_h == -1) + else if (_h == LatestBlock) return m_preMine; else return State(m_stateDB, m_bc, m_bc.numberHash(numberOf(_h))); @@ -768,7 +768,7 @@ eth::State Client::state(unsigned _txi) const return m_postMine.fromPending(_txi); } -StateDiff Client::diff(unsigned _txi, int _block) const +StateDiff Client::diff(unsigned _txi, BlockNumber _block) const { State st = asOf(_block); return st.fromPending(_txi).diff(st.fromPending(_txi + 1)); @@ -780,7 +780,7 @@ StateDiff Client::diff(unsigned _txi, h256 _block) const return st.fromPending(_txi).diff(st.fromPending(_txi + 1)); } -std::vector
Client::addresses(int _block) const +std::vector
Client::addresses(BlockNumber _block) const { vector
ret; for (auto const& i: asOf(_block).addresses()) @@ -788,27 +788,27 @@ std::vector
Client::addresses(int _block) const return ret; } -u256 Client::balanceAt(Address _a, int _block) const +u256 Client::balanceAt(Address _a, BlockNumber _block) const { return asOf(_block).balance(_a); } -std::map Client::storageAt(Address _a, int _block) const +std::map Client::storageAt(Address _a, BlockNumber _block) const { return asOf(_block).storage(_a); } -u256 Client::countAt(Address _a, int _block) const +u256 Client::countAt(Address _a, BlockNumber _block) const { return asOf(_block).transactionsFrom(_a); } -u256 Client::stateAt(Address _a, u256 _l, int _block) const +u256 Client::stateAt(Address _a, u256 _l, BlockNumber _block) const { return asOf(_block).storage(_a, _l); } -bytes Client::codeAt(Address _a, int _block) const +bytes Client::codeAt(Address _a, BlockNumber _block) const { return asOf(_block).code(_a); } diff --git a/libethereum/Client.h b/libethereum/Client.h index 426c78ca7..f34eea5bf 100644 --- a/libethereum/Client.h +++ b/libethereum/Client.h @@ -225,11 +225,11 @@ public: virtual void flushTransactions() override; /// Makes the given call. Nothing is recorded into the state. - virtual ExecutionResult call(Secret _secret, u256 _value, Address _dest, bytes const& _data = bytes(), u256 _gas = 10000, u256 _gasPrice = 10 * szabo, int _blockNumber = 0) override; + virtual ExecutionResult call(Secret _secret, u256 _value, Address _dest, bytes const& _data = bytes(), u256 _gas = 10000, u256 _gasPrice = 10 * szabo, BlockNumber _blockNumber = PendingBlock) override; /// Does the given creation. Nothing is recorded into the state. /// @returns the pair of the Address of the created contract together with its code. - virtual ExecutionResult create(Secret _secret, u256 _value, bytes const& _data = bytes(), u256 _gas = 10000, u256 _gasPrice = 10 * szabo, int _blockNumber = 0) override; + virtual ExecutionResult create(Secret _secret, u256 _value, bytes const& _data = bytes(), u256 _gas = 10000, u256 _gasPrice = 10 * szabo, BlockNumber _blockNumber = PendingBlock) override; /// Makes the given call. Nothing is recorded into the state. This cheats by creating a null address and endowing it with a lot of ETH. ExecutionResult call(Address _dest, bytes const& _data = bytes(), u256 _gas = 125000, u256 _value = 0, u256 _gasPrice = 1 * ether); @@ -244,11 +244,11 @@ public: using Interface::codeAt; using Interface::storageAt; - virtual u256 balanceAt(Address _a, int _block) const; - virtual u256 countAt(Address _a, int _block) const; - virtual u256 stateAt(Address _a, u256 _l, int _block) const; - virtual bytes codeAt(Address _a, int _block) const; - virtual std::map storageAt(Address _a, int _block) const; + virtual u256 balanceAt(Address _a, BlockNumber _block) const; + virtual u256 countAt(Address _a, BlockNumber _block) const; + virtual u256 stateAt(Address _a, u256 _l, BlockNumber _block) const; + virtual bytes codeAt(Address _a, BlockNumber _block) const; + virtual std::map storageAt(Address _a, BlockNumber _block) const; virtual unsigned installWatch(LogFilter const& _filter, Reaping _r = Reaping::Automatic) override; virtual unsigned installWatch(h256 _filterId, Reaping _r = Reaping::Automatic) override; @@ -282,11 +282,11 @@ public: /// Differences between transactions. using Interface::diff; virtual StateDiff diff(unsigned _txi, h256 _block) const; - virtual StateDiff diff(unsigned _txi, int _block) const; + virtual StateDiff diff(unsigned _txi, BlockNumber _block) const; /// Get a list of all active addresses. using Interface::addresses; - virtual std::vector
addresses(int _block) const; + virtual std::vector
addresses(BlockNumber _block) const; /// Get the remaining gas limit in this block. virtual u256 gasLimitRemaining() const { return m_postMine.gasLimitRemaining(); } @@ -383,7 +383,8 @@ private: /// Return the actual block number of the block with the given int-number (positive is the same, INT_MIN is genesis block, < 0 is negative age, thus -1 is most recently mined, 0 is pending. unsigned numberOf(int _b) const; - State asOf(int _h) const; + /// Returns the state object for the full block (i.e. the terminal state) for index _h. + /// Works properly with LatestBlock and PendingBlock. State asOf(unsigned _h) const; VersionChecker m_vc; ///< Dummy object to check & update the protocol version. diff --git a/libethereum/Interface.h b/libethereum/Interface.h index dfbd47704..68eb4b094 100644 --- a/libethereum/Interface.h +++ b/libethereum/Interface.h @@ -73,16 +73,16 @@ public: virtual void flushTransactions() = 0; /// Makes the given call. Nothing is recorded into the state. - virtual ExecutionResult call(Secret _secret, u256 _value, Address _dest, bytes const& _data = bytes(), u256 _gas = 10000, u256 _gasPrice = 10 * szabo, int _blockNumber = 0) = 0; + virtual ExecutionResult call(Secret _secret, u256 _value, Address _dest, bytes const& _data = bytes(), u256 _gas = 10000, u256 _gasPrice = 10 * szabo, BlockNumber _blockNumber = 0) = 0; /// Does the given creation. Nothing is recorded into the state. /// @returns the pair of the Address of the created contract together with its code. - virtual ExecutionResult create(Secret _secret, u256 _value, bytes const& _data = bytes(), u256 _gas = 10000, u256 _gasPrice = 10 * szabo, int _blockNumber = 0) = 0; + virtual ExecutionResult create(Secret _secret, u256 _value, bytes const& _data = bytes(), u256 _gas = 10000, u256 _gasPrice = 10 * szabo, BlockNumber _blockNumber = 0) = 0; // [STATE-QUERY API] int getDefault() const { return m_default; } - void setDefault(int _block) { m_default = _block; } + void setDefault(BlockNumber _block) { m_default = _block; } u256 balanceAt(Address _a) const { return balanceAt(_a, m_default); } u256 countAt(Address _a) const { return countAt(_a, m_default); } @@ -90,11 +90,11 @@ public: bytes codeAt(Address _a) const { return codeAt(_a, m_default); } std::map storageAt(Address _a) const { return storageAt(_a, m_default); } - virtual u256 balanceAt(Address _a, int _block) const = 0; - virtual u256 countAt(Address _a, int _block) const = 0; - virtual u256 stateAt(Address _a, u256 _l, int _block) const = 0; - virtual bytes codeAt(Address _a, int _block) const = 0; - virtual std::map storageAt(Address _a, int _block) const = 0; + virtual u256 balanceAt(Address _a, BlockNumber _block) const = 0; + virtual u256 countAt(Address _a, BlockNumber _block) const = 0; + virtual u256 stateAt(Address _a, u256 _l, BlockNumber _block) const = 0; + virtual bytes codeAt(Address _a, BlockNumber _block) const = 0; + virtual std::map storageAt(Address _a, BlockNumber _block) const = 0; // [LOGS API] @@ -135,11 +135,11 @@ public: /// Differences between transactions. StateDiff diff(unsigned _txi) const { return diff(_txi, m_default); } virtual StateDiff diff(unsigned _txi, h256 _block) const = 0; - virtual StateDiff diff(unsigned _txi, int _block) const = 0; + virtual StateDiff diff(unsigned _txi, BlockNumber _block) const = 0; /// Get a list of all active addresses. virtual Addresses addresses() const { return addresses(m_default); } - virtual Addresses addresses(int _block) const = 0; + virtual Addresses addresses(BlockNumber _block) const = 0; /// Get the fee associated for a transaction with the given data. template static bigint txGas(T const& _data, u256 _gas = 0) { bigint ret = c_txGas + _gas; for (auto i: _data) ret += i ? c_txDataNonZeroGas : c_txDataZeroGas; return ret; } @@ -177,7 +177,7 @@ public: virtual MineProgress miningProgress() const = 0; protected: - int m_default = -1; + int m_default = PendingBlock; }; class Watch; diff --git a/libethereum/LogFilter.cpp b/libethereum/LogFilter.cpp index a2a1aa40e..ab9848d59 100644 --- a/libethereum/LogFilter.cpp +++ b/libethereum/LogFilter.cpp @@ -46,7 +46,7 @@ h256 LogFilter::sha3() const return dev::sha3(s.out()); } -static bool isNoLater(RelativeBlock _logBlockRelation, u256 _logBlockNumber, int _latest) +static bool isNoLater(RelativeBlock _logBlockRelation, u256 _logBlockNumber, unsigned _latest) { if (_latest == PendingBlock) return true; @@ -56,7 +56,7 @@ static bool isNoLater(RelativeBlock _logBlockRelation, u256 _logBlockNumber, int return _logBlockNumber <= _latest; } -static bool isNoEarlier(RelativeBlock _logBlockRelation, u256 _logBlockNumber, int _earliest) +static bool isNoEarlier(RelativeBlock _logBlockRelation, u256 _logBlockNumber, unsigned _earliest) { if (_earliest == PendingBlock) return _logBlockRelation == RelativeBlock::Pending; diff --git a/libethereum/LogFilter.h b/libethereum/LogFilter.h index 7b808a0eb..304fab317 100644 --- a/libethereum/LogFilter.h +++ b/libethereum/LogFilter.h @@ -42,15 +42,6 @@ std::ostream& operator<<(std::ostream& _out, dev::eth::LogFilter const& _s); class State; -enum class RelativeBlock -{ - Latest, - Pending -}; - -static const unsigned LatestBlock = (unsigned)-2; -static const unsigned PendingBlock = (unsigned)-1; - class LogFilter { public: diff --git a/libweb3jsonrpc/WebThreeStubServerBase.cpp b/libweb3jsonrpc/WebThreeStubServerBase.cpp index 1bbd8b404..e972136d6 100644 --- a/libweb3jsonrpc/WebThreeStubServerBase.cpp +++ b/libweb3jsonrpc/WebThreeStubServerBase.cpp @@ -139,7 +139,7 @@ static Json::Value toJson(map const& _storage) return res; } -static unsigned jsToBlockIndex(std::string const& _js) +static unsigned toBlockNumber(std::string const& _js) { if (_js == "latest") return LatestBlock; @@ -159,9 +159,9 @@ static dev::eth::LogFilter toLogFilter(Json::Value const& _json) // commented to // check only !empty. it should throw exceptions if input params are incorrect if (!_json["fromBlock"].empty()) - filter.withEarliest(jsToBlockIndex(_json["fromBlock"].asString())); + filter.withEarliest(toBlockNumber(_json["fromBlock"].asString())); if (!_json["toBlock"].empty()) - filter.withLatest(jsToBlockIndex(_json["toBlock"].asString())); + filter.withLatest(toBlockNumber(_json["toBlock"].asString())); if (!_json["address"].empty()) { if (_json["address"].isArray()) @@ -239,16 +239,6 @@ static Json::Value toJson(h256 const& _h, shh::Envelope const& _e, shh::Message return res; } -// TODO: convert to jsToBlockNumber, downstream. too. -static int toBlockNumber(string const& _string) -{ - if (_string.compare("latest") == 0) - return -1; - if (_string.compare("pending") == 0) - return 0; - return jsToInt(_string); -} - WebThreeStubServerBase::WebThreeStubServerBase(AbstractServerConnector& _conn, vector const& _accounts): AbstractWebThreeStubServer(_conn), m_accounts(make_shared(bind(&WebThreeStubServerBase::client, this))) { diff --git a/mix/MixClient.cpp b/mix/MixClient.cpp index f61269005..fd7b2263d 100644 --- a/mix/MixClient.cpp +++ b/mix/MixClient.cpp @@ -283,7 +283,7 @@ void MixClient::flushTransactions() { } -dev::eth::ExecutionResult MixClient::call(Secret _secret, u256 _value, Address _dest, bytes const& _data, u256 _gas, u256 _gasPrice, int _blockNumber) +dev::eth::ExecutionResult MixClient::call(Secret _secret, u256 _value, Address _dest, bytes const& _data, u256 _gas, u256 _gasPrice, BlockNumber _blockNumber) { u256 n; State temp; @@ -299,7 +299,7 @@ dev::eth::ExecutionResult MixClient::call(Secret _secret, u256 _value, Address _ return lastExecution().result; } -dev::eth::ExecutionResult MixClient::create(Secret _secret, u256 _value, bytes const& _data, u256 _gas, u256 _gasPrice, int _blockNumber) +dev::eth::ExecutionResult MixClient::create(Secret _secret, u256 _value, bytes const& _data, u256 _gas, u256 _gasPrice, BlockNumber _blockNumber) { u256 n; State temp; @@ -315,27 +315,27 @@ dev::eth::ExecutionResult MixClient::create(Secret _secret, u256 _value, bytes c return lastExecution().result; } -u256 MixClient::balanceAt(Address _a, int _block) const +u256 MixClient::balanceAt(Address _a, BlockNumber _block) const { return asOf(_block).balance(_a); } -u256 MixClient::countAt(Address _a, int _block) const +u256 MixClient::countAt(Address _a, BlockNumber _block) const { return asOf(_block).transactionsFrom(_a); } -u256 MixClient::stateAt(Address _a, u256 _l, int _block) const +u256 MixClient::stateAt(Address _a, u256 _l, BlockNumber _block) const { return asOf(_block).storage(_a, _l); } -bytes MixClient::codeAt(Address _a, int _block) const +bytes MixClient::codeAt(Address _a, BlockNumber _block) const { return asOf(_block).code(_a); } -std::map MixClient::storageAt(Address _a, int _block) const +std::map MixClient::storageAt(Address _a, BlockNumber _block) const { return asOf(_block).storage(_a); } @@ -567,13 +567,13 @@ eth::StateDiff MixClient::diff(unsigned _txi, h256 _block) const return st.fromPending(_txi).diff(st.fromPending(_txi + 1)); } -eth::StateDiff MixClient::diff(unsigned _txi, int _block) const +eth::StateDiff MixClient::diff(unsigned _txi, BlockNumber _block) const { State st = asOf(_block); return st.fromPending(_txi).diff(st.fromPending(_txi + 1)); } -Addresses MixClient::addresses(int _block) const +Addresses MixClient::addresses(BlockNumber _block) const { Addresses ret; for (auto const& i: asOf(_block).addresses()) diff --git a/mix/MixClient.h b/mix/MixClient.h index 37b2bb5d2..e1085a20e 100644 --- a/mix/MixClient.h +++ b/mix/MixClient.h @@ -25,6 +25,7 @@ #include #include +#include #include #include #include "MachineStates.h" @@ -52,13 +53,13 @@ public: Address submitTransaction(Secret _secret, u256 _endowment, bytes const& _init, u256 _gas, u256 _gasPrice) override; void inject(bytesConstRef _rlp) override; void flushTransactions() override; - dev::eth::ExecutionResult call(Secret _secret, u256 _value, Address _dest, bytes const& _data, u256 _gas, u256 _gasPrice, int _blockNumber) override; - dev::eth::ExecutionResult create(Secret _secret, u256 _value, bytes const& _data, u256 _gas, u256 _gasPrice, int _blockNumber) override; - u256 balanceAt(Address _a, int _block) const override; - u256 countAt(Address _a, int _block) const override; - u256 stateAt(Address _a, u256 _l, int _block) const override; - bytes codeAt(Address _a, int _block) const override; - std::map storageAt(Address _a, int _block) const override; + dev::eth::ExecutionResult call(Secret _secret, u256 _value, Address _dest, bytes const& _data, u256 _gas, u256 _gasPrice, eth::BlockNumber _blockNumber) override; + dev::eth::ExecutionResult create(Secret _secret, u256 _value, bytes const& _data, u256 _gas, u256 _gasPrice, eth::BlockNumber _blockNumber) override; + u256 balanceAt(Address _a, eth::BlockNumber _block) const override; + u256 countAt(Address _a, eth::BlockNumber _block) const override; + u256 stateAt(Address _a, u256 _l, eth::BlockNumber _block) const override; + bytes codeAt(Address _a, eth::BlockNumber _block) const override; + std::map storageAt(Address _a, eth::BlockNumber _block) const override; eth::LocalisedLogEntries logs(unsigned _watchId) const override; eth::LocalisedLogEntries logs(eth::LogFilter const& _filter) const override; unsigned installWatch(eth::LogFilter const& _filter, eth::Reaping _r = eth::Reaping::Automatic) override; @@ -79,8 +80,8 @@ public: unsigned number() const override; eth::Transactions pending() const override; eth::StateDiff diff(unsigned _txi, h256 _block) const override; - eth::StateDiff diff(unsigned _txi, int _block) const override; - Addresses addresses(int _block) const override; + eth::StateDiff diff(unsigned _txi, eth::BlockNumber _block) const override; + Addresses addresses(eth::BlockNumber _block) const override; u256 gasLimitRemaining() const override; void setAddress(Address _us) override; Address address() const override; diff --git a/neth/main.cpp b/neth/main.cpp index 5fa48dd7f..275ac3ea4 100644 --- a/neth/main.cpp +++ b/neth/main.cpp @@ -954,7 +954,7 @@ int main(int argc, char** argv) auto s = t.receiveAddress() ? boost::format(" %1% %2%> %3%: %4% [%5%]") % toString(t.safeSender()) % - (c->codeAt(t.receiveAddress(), 0).size() ? '*' : '-') % + (c->codeAt(t.receiveAddress(), PendingBlock).size() ? '*' : '-') % toString(t.receiveAddress()) % toString(formatBalance(t.value())) % toString((unsigned)t.nonce()) : @@ -979,7 +979,7 @@ int main(int argc, char** argv) auto s = t.receiveAddress() ? boost::format("%1% %2%> %3%: %4% [%5%]") % toString(t.safeSender()) % - (c->codeAt(t.receiveAddress(), 0).size() ? '*' : '-') % + (c->codeAt(t.receiveAddress(), PendingBlock).size() ? '*' : '-') % toString(t.receiveAddress()) % toString(formatBalance(t.value())) % toString((unsigned)t.nonce()) : @@ -999,25 +999,25 @@ int main(int argc, char** argv) int cc = 1; auto acs = c->addresses(); for (auto const& i: acs) - if (c->codeAt(i, 0).size()) + if (c->codeAt(i, PendingBlock).size()) { auto s = boost::format("%1%%2% : %3% [%4%]") % toString(i) % pretty(i, c->postState()) % toString(formatBalance(c->balanceAt(i))) % - toString((unsigned)c->countAt(i, 0)); + toString((unsigned)c->countAt(i, PendingBlock)); mvwaddnstr(contractswin, cc++, x, s.str().c_str(), qwidth); if (cc > qheight - 2) break; } for (auto const& i: acs) - if (c->codeAt(i, 0).empty()) + if (c->codeAt(i, PendingBlock).empty()) { auto s = boost::format("%1%%2% : %3% [%4%]") % toString(i) % pretty(i, c->postState()) % toString(formatBalance(c->balanceAt(i))) % - toString((unsigned)c->countAt(i, 0)); + toString((unsigned)c->countAt(i, PendingBlock)); mvwaddnstr(addswin, y++, x, s.str().c_str(), width / 2 - 4); if (y > height * 3 / 5 - 4) break; diff --git a/third/MainWin.cpp b/third/MainWin.cpp index a1074cddb..b03723131 100644 --- a/third/MainWin.cpp +++ b/third/MainWin.cpp @@ -212,13 +212,13 @@ void Main::installWatches() void Main::installNameRegWatch() { ethereum()->uninstallWatch(m_nameRegFilter); - m_nameRegFilter = installWatch(dev::eth::LogFilter().address(u160(ethereum()->stateAt(c_config, 0))), [=](LocalisedLogEntries const&){ onNameRegChange(); }); + m_nameRegFilter = installWatch(dev::eth::LogFilter().address(u160(ethereum()->stateAt(c_config, PendingBlock))), [=](LocalisedLogEntries const&){ onNameRegChange(); }); } void Main::installCurrenciesWatch() { ethereum()->uninstallWatch(m_currenciesFilter); - m_currenciesFilter = installWatch(dev::eth::LogFilter().address(u160(ethereum()->stateAt(c_config, 1))), [=](LocalisedLogEntries const&){ onCurrenciesChange(); }); + m_currenciesFilter = installWatch(dev::eth::LogFilter().address(u160(ethereum()->stateAt(c_config, LatestBlock))), [=](LocalisedLogEntries const&){ onCurrenciesChange(); }); } void Main::installBalancesWatch() @@ -226,8 +226,8 @@ void Main::installBalancesWatch() dev::eth::LogFilter tf; vector
altCoins; - Address coinsAddr = right160(ethereum()->stateAt(c_config, 1)); - for (unsigned i = 0; i < ethereum()->stateAt(coinsAddr, 0); ++i) + Address coinsAddr = right160(ethereum()->stateAt(c_config, LatestBlock)); + for (unsigned i = 0; i < ethereum()->stateAt(coinsAddr, PendingBlock); ++i) altCoins.push_back(right160(ethereum()->stateAt(coinsAddr, i + 1))); for (auto i: m_myKeys) for (auto c: altCoins) @@ -294,7 +294,7 @@ QString Main::pretty(dev::Address _a) const { h256 n; - if (h160 nameReg = (u160)ethereum()->stateAt(c_config, 0)) + if (h160 nameReg = (u160)ethereum()->stateAt(c_config, PendingBlock)) n = ethereum()->stateAt(nameReg, (u160)(_a)); return fromRaw(n); @@ -321,7 +321,7 @@ Address Main::fromString(QString const& _a) const memset(n.data() + sn.size(), 0, 32 - sn.size()); if (_a.size()) { - if (h160 nameReg = (u160)ethereum()->stateAt(c_config, 0)) + if (h160 nameReg = (u160)ethereum()->stateAt(c_config, PendingBlock)) if (h256 a = ethereum()->stateAt(nameReg, n)) return right160(a); } @@ -350,10 +350,10 @@ QString Main::lookup(QString const& _a) const */ h256 ret; - if (h160 dnsReg = (u160)ethereum()->stateAt(c_config, 4, 0)) + if (h160 dnsReg = (u160)ethereum()->stateAt(c_config, 4, PendingBlock)) ret = ethereum()->stateAt(dnsReg, n); /* if (!ret) - if (h160 nameReg = (u160)ethereum()->stateAt(c_config, 0, 0)) + if (h160 nameReg = (u160)ethereum()->stateAt(c_config, 0, PendingBlock)) ret = ethereum()->stateAt(nameReg, n2); */ if (ret && !((u256)ret >> 32)) @@ -476,8 +476,8 @@ void Main::refreshBalances() ui->ourAccounts->clear(); u256 totalBalance = 0; map> altCoins; - Address coinsAddr = right160(ethereum()->stateAt(c_config, 1)); - for (unsigned i = 0; i < ethereum()->stateAt(coinsAddr, 0); ++i) + Address coinsAddr = right160(ethereum()->stateAt(c_config, LatestBlock)); + for (unsigned i = 0; i < ethereum()->stateAt(coinsAddr, PendingBlock); ++i) altCoins[right160(ethereum()->stateAt(coinsAddr, ethereum()->stateAt(coinsAddr, i + 1)))] = make_pair(fromRaw(ethereum()->stateAt(coinsAddr, i + 1)), 0); for (auto i: m_myKeys) { From 07c5cc33e116a6e0761891fefdeb375b576d2edf Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Sat, 21 Mar 2015 19:53:33 +0100 Subject: [PATCH 20/66] Fixes #1369 --- libevm/ExtVMFace.h | 4 +-- libjsqrc/ethereumjs/dist/ethereum.js | 32 ++++++++++------------- libjsqrc/ethereumjs/dist/ethereum.js.map | 8 +++--- libjsqrc/ethereumjs/dist/ethereum.min.js | 2 +- libjsqrc/ethereumjs/lib/web3/contract.js | 2 +- libjsqrc/ethereumjs/lib/web3/filter.js | 27 ++++++++----------- libweb3jsonrpc/WebThreeStubServerBase.cpp | 20 +++++++------- 7 files changed, 44 insertions(+), 51 deletions(-) diff --git a/libevm/ExtVMFace.h b/libevm/ExtVMFace.h index 79b97a252..48fbd0b01 100644 --- a/libevm/ExtVMFace.h +++ b/libevm/ExtVMFace.h @@ -63,10 +63,10 @@ using LogEntries = std::vector; struct LocalisedLogEntry: public LogEntry { LocalisedLogEntry() {} - LocalisedLogEntry(LogEntry const& _le, unsigned _number, h256 _sha3 = {}): LogEntry(_le), number(_number), sha3(_sha3) {} + LocalisedLogEntry(LogEntry const& _le, unsigned _number, h256 _transactionHash = h256()): LogEntry(_le), number(_number), transactionHash(_transactionHash) {} unsigned number = 0; - h256 sha3; + h256 transactionHash; }; using LocalisedLogEntries = std::vector; diff --git a/libjsqrc/ethereumjs/dist/ethereum.js b/libjsqrc/ethereumjs/dist/ethereum.js index 4ae476ca5..d8f1a7cef 100644 --- a/libjsqrc/ethereumjs/dist/ethereum.js +++ b/libjsqrc/ethereumjs/dist/ethereum.js @@ -1527,7 +1527,7 @@ var addEventsToContract = function (contract, desc, address) { var parser = eventImpl.outputParser(e); return parser(data); }; - return web3.eth.filter(o, undefined, undefined, outputFormatter); + return web3.eth.filter(o, undefined, undefined, outputFormatter); }; // this property should be used by eth.filter to check if object is an event @@ -2005,16 +2005,6 @@ var getOptions = function (options) { options.toBlock = options.latest; } - if (options.skip) { - console.warn('"skip" is deprecated, is "offset" instead'); - options.offset = options.skip; - } - - if (options.max) { - console.warn('"max" is deprecated, is "limit" instead'); - options.limit = options.max; - } - // make sure topics, get converted to hex if(options.topics instanceof Array) { options.topics = options.topics.map(function(topic){ @@ -2022,13 +2012,18 @@ var getOptions = function (options) { }); } + var asBlockNumber = function(n) { + if (n == null) + return null; + if (n == 'latest' || n == 'pending') + return n; + return utils.toHex(n); + }; // evaluate lazy properties return { - fromBlock: utils.toHex(options.fromBlock), - toBlock: utils.toHex(options.toBlock), - limit: utils.toHex(options.limit), - offset: utils.toHex(options.offset), + fromBlock: asBlockNumber(options.fromBlock), + toBlock: asBlockNumber(options.toBlock), to: options.to, address: options.address, topics: options.topics @@ -2053,9 +2048,10 @@ var filter = function(options, implementation, formatter) { // call the callbacks var onMessages = function (messages) { messages.forEach(function (message) { - message = formatter ? formatter(message) : message; + console.log("Got message: " + JSON.stringify(message)); + message = formatter ? formatter(message) : message; callbacks.forEach(function (callback) { - callback(message); + callback(message); }); }); }; @@ -2855,4 +2851,4 @@ module.exports = web3; },{"./lib/solidity/abi":1,"./lib/web3":6,"./lib/web3/contract":7,"./lib/web3/httpprovider":13,"./lib/web3/qtsync":16}]},{},["web3"]) -//# sourceMappingURL=ethereum.js.map +//# sourceMappingURL=ethereum.js.map \ No newline at end of file diff --git a/libjsqrc/ethereumjs/dist/ethereum.js.map b/libjsqrc/ethereumjs/dist/ethereum.js.map index a36e9ed17..0c38ccdbc 100644 --- a/libjsqrc/ethereumjs/dist/ethereum.js.map +++ b/libjsqrc/ethereumjs/dist/ethereum.js.map @@ -26,7 +26,7 @@ "index.js" ], "names": [], - "mappings": "AAAA;ACAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACrPA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACtNA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC7EA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACvEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AChcA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC5SA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACnPA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACpCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACrJA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1IA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AChLA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC3MA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACrEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACjEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACzCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACjCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACjKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACjDA;AACA;AACA;;ACFA;AACA;AACA;AACA;AACA;AACA;AACA;AACA", + "mappings": "AAAA;ACAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACrPA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACtNA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC7EA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACvEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AChcA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC5SA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACnPA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACpCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACpJA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1IA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC5KA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC3MA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACrEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACjEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACzCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACjCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACjKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACjDA;AACA;AACA;;ACFA;AACA;AACA;AACA;AACA;AACA;AACA;AACA", "file": "generated.js", "sourceRoot": "", "sourcesContent": [ @@ -37,11 +37,11 @@ "/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/** @file config.js\n * @authors:\n * Marek Kotewicz \n * @date 2015\n */\n\n/**\n * Utils\n * \n * @module utils\n */\n\n/**\n * Utility functions\n * \n * @class [utils] config\n * @constructor\n */\n\n/// required to define ETH_BIGNUMBER_ROUNDING_MODE\nif (\"build\" !== 'build') {/*\n var BigNumber = require('bignumber.js'); // jshint ignore:line\n*/}\n\nvar ETH_UNITS = [ \n 'wei', \n 'Kwei', \n 'Mwei', \n 'Gwei', \n 'szabo', \n 'finney', \n 'ether', \n 'grand', \n 'Mether', \n 'Gether', \n 'Tether', \n 'Pether', \n 'Eether', \n 'Zether', \n 'Yether', \n 'Nether', \n 'Dether', \n 'Vether', \n 'Uether' \n];\n\nmodule.exports = {\n ETH_PADDING: 32,\n ETH_SIGNATURE_LENGTH: 4,\n ETH_UNITS: ETH_UNITS,\n ETH_BIGNUMBER_ROUNDING_MODE: { ROUNDING_MODE: BigNumber.ROUND_DOWN },\n ETH_POLLING_TIMEOUT: 1000,\n ETH_DEFAULTBLOCK: 'latest'\n};\n\n", "/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/** @file utils.js\n * @authors:\n * Marek Kotewicz \n * @date 2015\n */\n\n/**\n * Utils\n * \n * @module utils\n */\n\n/**\n * Utility functions\n * \n * @class [utils] utils\n * @constructor\n */\n\nif (\"build\" !== 'build') {/*\n var BigNumber = require('bignumber.js'); // jshint ignore:line\n*/}\n\nvar unitMap = {\n 'wei': '1',\n 'kwei': '1000',\n 'ada': '1000',\n 'mwei': '1000000',\n 'babbage': '1000000',\n 'gwei': '1000000000',\n 'shannon': '1000000000',\n 'szabo': '1000000000000',\n 'finney': '1000000000000000',\n 'ether': '1000000000000000000',\n 'kether': '1000000000000000000000',\n 'grand': '1000000000000000000000',\n 'einstein': '1000000000000000000000',\n 'mether': '1000000000000000000000000',\n 'gether': '1000000000000000000000000000',\n 'tether': '1000000000000000000000000000000'\n};\n\n\n/** Finds first index of array element matching pattern\n *\n * @method findIndex\n * @param {Array}\n * @param {Function} pattern\n * @returns {Number} index of element\n */\nvar findIndex = function (array, callback) {\n var end = false;\n var i = 0;\n for (; i < array.length && !end; i++) {\n end = callback(array[i]);\n }\n return end ? i - 1 : -1;\n};\n\n/** \n * Should be called to get sting from it's hex representation\n *\n * @method toAscii\n * @param {String} string in hex\n * @returns {String} ascii string representation of hex value\n */\nvar toAscii = function(hex) {\n// Find termination\n var str = \"\";\n var i = 0, l = hex.length;\n if (hex.substring(0, 2) === '0x') {\n i = 2;\n }\n for (; i < l; i+=2) {\n var code = parseInt(hex.substr(i, 2), 16);\n if (code === 0) {\n break;\n }\n\n str += String.fromCharCode(code);\n }\n\n return str;\n};\n \n/**\n * Shold be called to get hex representation (prefixed by 0x) of ascii string \n *\n * @method fromAscii\n * @param {String} string\n * @returns {String} hex representation of input string\n */\nvar toHexNative = function(str) {\n var hex = \"\";\n for(var i = 0; i < str.length; i++) {\n var n = str.charCodeAt(i).toString(16);\n hex += n.length < 2 ? '0' + n : n;\n }\n\n return hex;\n};\n\n/**\n * Shold be called to get hex representation (prefixed by 0x) of ascii string \n *\n * @method fromAscii\n * @param {String} string\n * @param {Number} optional padding\n * @returns {String} hex representation of input string\n */\nvar fromAscii = function(str, pad) {\n pad = pad === undefined ? 0 : pad;\n var hex = toHexNative(str);\n while (hex.length < pad*2)\n hex += \"00\";\n return \"0x\" + hex;\n};\n\n/**\n * Should be called to get display name of contract function\n * \n * @method extractDisplayName\n * @param {String} name of function/event\n * @returns {String} display name for function/event eg. multiply(uint256) -> multiply\n */\nvar extractDisplayName = function (name) {\n var length = name.indexOf('('); \n return length !== -1 ? name.substr(0, length) : name;\n};\n\n/// @returns overloaded part of function/event name\nvar extractTypeName = function (name) {\n /// TODO: make it invulnerable\n var length = name.indexOf('(');\n return length !== -1 ? name.substr(length + 1, name.length - 1 - (length + 1)).replace(' ', '') : \"\";\n};\n\n/**\n * Filters all functions from input abi\n *\n * @method filterFunctions\n * @param {Array} abi\n * @returns {Array} abi array with filtered objects of type 'function'\n */\nvar filterFunctions = function (json) {\n return json.filter(function (current) {\n return current.type === 'function'; \n }); \n};\n\n/**\n * Filters all events from input abi\n *\n * @method filterEvents\n * @param {Array} abi\n * @returns {Array} abi array with filtered objects of type 'event'\n */\nvar filterEvents = function (json) {\n return json.filter(function (current) {\n return current.type === 'event';\n });\n};\n\n/**\n * Converts value to it's decimal representation in string\n *\n * @method toDecimal\n * @param {String|Number|BigNumber}\n * @return {String}\n */\nvar toDecimal = function (value) {\n return toBigNumber(value).toNumber();\n};\n\n/**\n * Converts value to it's hex representation\n *\n * @method fromDecimal\n * @param {String|Number|BigNumber}\n * @return {String}\n */\nvar fromDecimal = function (value) {\n var number = toBigNumber(value);\n var result = number.toString(16);\n\n return number.lessThan(0) ? '-0x' + result.substr(1) : '0x' + result;\n};\n\n/**\n * Auto converts any given value into it's hex representation.\n *\n * And even stringifys objects before.\n *\n * @method toHex\n * @param {String|Number|BigNumber|Object}\n * @return {String}\n */\nvar toHex = function (val) {\n /*jshint maxcomplexity:7 */\n\n if(isBoolean(val))\n return val;\n\n if(isBigNumber(val))\n return fromDecimal(val);\n\n if(isObject(val))\n return fromAscii(JSON.stringify(val));\n\n // if its a negative number, pass it through fromDecimal\n if (isString(val)) {\n if (val.indexOf('-0x') === 0)\n return fromDecimal(val);\n else if (!isFinite(val))\n return fromAscii(val);\n }\n\n return fromDecimal(val);\n};\n\n/**\n * Returns value of unit in Wei\n *\n * @method getValueOfUnit\n * @param {String} unit the unit to convert to, default ether\n * @returns {BigNumber} value of the unit (in Wei)\n * @throws error if the unit is not correct:w\n */\nvar getValueOfUnit = function (unit) {\n unit = unit ? unit.toLowerCase() : 'ether';\n var unitValue = unitMap[unit];\n if (unitValue === undefined) {\n throw new Error('This unit doesn\\'t exists, please use the one of the following units' + JSON.stringify(unitMap, null, 2));\n }\n return new BigNumber(unitValue, 10);\n};\n\n/**\n * Takes a number of wei and converts it to any other ether unit.\n *\n * Possible units are:\n * - kwei/ada\n * - mwei/babbage\n * - gwei/shannon\n * - szabo\n * - finney\n * - ether\n * - kether/grand/einstein\n * - mether\n * - gether\n * - tether\n *\n * @method fromWei\n * @param {Number|String} number can be a number, number string or a HEX of a decimal\n * @param {String} unit the unit to convert to, default ether\n * @return {String|Object} When given a BigNumber object it returns one as well, otherwise a number\n*/\nvar fromWei = function(number, unit) {\n var returnValue = toBigNumber(number).dividedBy(getValueOfUnit(unit));\n\n return isBigNumber(number) ? returnValue : returnValue.toString(10); \n};\n\n/**\n * Takes a number of a unit and converts it to wei.\n *\n * Possible units are:\n * - kwei/ada\n * - mwei/babbage\n * - gwei/shannon\n * - szabo\n * - finney\n * - ether\n * - kether/grand/einstein\n * - mether\n * - gether\n * - tether\n *\n * @method toWei\n * @param {Number|String|BigNumber} number can be a number, number string or a HEX of a decimal\n * @param {String} unit the unit to convert from, default ether\n * @return {String|Object} When given a BigNumber object it returns one as well, otherwise a number\n*/\nvar toWei = function(number, unit) {\n var returnValue = toBigNumber(number).times(getValueOfUnit(unit));\n\n return isBigNumber(number) ? returnValue : returnValue.toString(10); \n};\n\n/**\n * Takes an input and transforms it into an bignumber\n *\n * @method toBigNumber\n * @param {Number|String|BigNumber} a number, string, HEX string or BigNumber\n * @return {BigNumber} BigNumber\n*/\nvar toBigNumber = function(number) {\n /*jshint maxcomplexity:5 */\n number = number || 0;\n if (isBigNumber(number))\n return number;\n\n if (isString(number) && (number.indexOf('0x') === 0 || number.indexOf('-0x') === 0)) {\n return new BigNumber(number.replace('0x',''), 16);\n }\n \n return new BigNumber(number.toString(10), 10);\n};\n\n/**\n * Takes and input transforms it into bignumber and if it is negative value, into two's complement\n *\n * @method toTwosComplement\n * @param {Number|String|BigNumber}\n * @return {BigNumber}\n */\nvar toTwosComplement = function (number) {\n var bigNumber = toBigNumber(number);\n if (bigNumber.lessThan(0)) {\n return new BigNumber(\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\", 16).plus(bigNumber).plus(1);\n }\n return bigNumber;\n};\n\n/**\n * Checks if the given string has proper length\n *\n * @method isAddress\n * @param {String} address the given HEX adress\n * @return {Boolean}\n*/\nvar isAddress = function(address) {\n if (!isString(address)) {\n return false;\n }\n\n return ((address.indexOf('0x') === 0 && address.length === 42) ||\n (address.indexOf('0x') === -1 && address.length === 40));\n};\n\n/**\n * Returns true if object is BigNumber, otherwise false\n *\n * @method isBigNumber\n * @param {Object}\n * @return {Boolean} \n */\nvar isBigNumber = function (object) {\n return object instanceof BigNumber ||\n (object && object.constructor && object.constructor.name === 'BigNumber');\n};\n\n/**\n * Returns true if object is string, otherwise false\n * \n * @method isString\n * @param {Object}\n * @return {Boolean}\n */\nvar isString = function (object) {\n return typeof object === 'string' ||\n (object && object.constructor && object.constructor.name === 'String');\n};\n\n/**\n * Returns true if object is function, otherwise false\n *\n * @method isFunction\n * @param {Object}\n * @return {Boolean}\n */\nvar isFunction = function (object) {\n return typeof object === 'function';\n};\n\n/**\n * Returns true if object is Objet, otherwise false\n *\n * @method isObject\n * @param {Object}\n * @return {Boolean}\n */\nvar isObject = function (object) {\n return typeof object === 'object';\n};\n\n/**\n * Returns true if object is boolean, otherwise false\n *\n * @method isBoolean\n * @param {Object}\n * @return {Boolean}\n */\nvar isBoolean = function (object) {\n return typeof object === 'boolean';\n};\n\n/**\n * Returns true if object is array, otherwise false\n *\n * @method isArray\n * @param {Object}\n * @return {Boolean}\n */\nvar isArray = function (object) {\n return object instanceof Array; \n};\n\nmodule.exports = {\n findIndex: findIndex,\n toHex: toHex,\n toDecimal: toDecimal,\n fromDecimal: fromDecimal,\n toAscii: toAscii,\n fromAscii: fromAscii,\n extractDisplayName: extractDisplayName,\n extractTypeName: extractTypeName,\n filterFunctions: filterFunctions,\n filterEvents: filterEvents,\n toWei: toWei,\n fromWei: fromWei,\n toBigNumber: toBigNumber,\n toTwosComplement: toTwosComplement,\n isBigNumber: isBigNumber,\n isAddress: isAddress,\n isFunction: isFunction,\n isString: isString,\n isObject: isObject,\n isBoolean: isBoolean,\n isArray: isArray\n};\n\n", "/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/** @file web3.js\n * @authors:\n * Jeffrey Wilcke \n * Marek Kotewicz \n * Marian Oancea \n * Fabian Vogelsteller \n * Gav Wood \n * @date 2014\n */\n\nvar version = require('../version.json');\nvar net = require('./web3/net');\nvar eth = require('./web3/eth');\nvar db = require('./web3/db');\nvar shh = require('./web3/shh');\nvar watches = require('./web3/watches');\nvar filter = require('./web3/filter');\nvar utils = require('./utils/utils');\nvar formatters = require('./solidity/formatters');\nvar requestManager = require('./web3/requestmanager');\nvar c = require('./utils/config');\n\n/// @returns an array of objects describing web3 api methods\nvar web3Methods = [\n { name: 'sha3', call: 'web3_sha3', inputFormatter: utils.toHex },\n];\nvar web3Properties = [\n { name: 'version.client', getter: 'web3_clientVersion' },\n { name: 'version.network', getter: 'net_version' }\n];\n\n\n/// creates methods in a given object based on method description on input\n/// setups api calls for these methods\nvar setupMethods = function (obj, methods) {\n methods.forEach(function (method) {\n // allow for object methods 'myObject.method'\n var objectMethods = method.name.split('.'),\n callFunction = function () {\n /*jshint maxcomplexity:8 */\n \n var callback = null,\n args = Array.prototype.slice.call(arguments),\n call = typeof method.call === 'function' ? method.call(args) : method.call;\n\n // get the callback if one is available\n if(typeof args[args.length-1] === 'function'){\n callback = args[args.length-1];\n Array.prototype.pop.call(args);\n }\n\n // add the defaultBlock if not given\n if(method.addDefaultblock) {\n if(args.length !== method.addDefaultblock)\n Array.prototype.push.call(args, (isFinite(c.ETH_DEFAULTBLOCK) ? utils.fromDecimal(c.ETH_DEFAULTBLOCK) : c.ETH_DEFAULTBLOCK));\n else\n args[args.length-1] = isFinite(args[args.length-1]) ? utils.fromDecimal(args[args.length-1]) : args[args.length-1];\n }\n\n // show deprecated warning\n if(method.newMethod)\n console.warn('This method is deprecated please use web3.'+ method.newMethod +'() instead.');\n\n return web3.manager.send({\n method: call,\n params: args,\n outputFormatter: method.outputFormatter,\n inputFormatter: method.inputFormatter,\n addDefaultblock: method.addDefaultblock\n }, callback);\n };\n\n if(objectMethods.length > 1) {\n if(!obj[objectMethods[0]])\n obj[objectMethods[0]] = {};\n\n obj[objectMethods[0]][objectMethods[1]] = callFunction;\n \n } else {\n\n obj[objectMethods[0]] = callFunction;\n }\n\n });\n};\n\n/// creates properties in a given object based on properties description on input\n/// setups api calls for these properties\nvar setupProperties = function (obj, properties) {\n properties.forEach(function (property) {\n var objectProperties = property.name.split('.'),\n proto = {};\n\n proto.get = function () {\n\n // show deprecated warning\n if(property.newProperty)\n console.warn('This property is deprecated please use web3.'+ property.newProperty +' instead.');\n\n\n return web3.manager.send({\n method: property.getter,\n outputFormatter: property.outputFormatter\n });\n };\n\n if (property.setter) {\n proto.set = function (val) {\n\n // show deprecated warning\n if(property.newProperty)\n console.warn('This property is deprecated please use web3.'+ property.newProperty +' instead.');\n\n return web3.manager.send({\n method: property.setter,\n params: [val],\n inputFormatter: property.inputFormatter\n });\n };\n }\n\n proto.enumerable = !property.newProperty;\n\n if(objectProperties.length > 1) {\n if(!obj[objectProperties[0]])\n obj[objectProperties[0]] = {};\n\n Object.defineProperty(obj[objectProperties[0]], objectProperties[1], proto); \n } else\n Object.defineProperty(obj, property.name, proto);\n\n });\n};\n\n/*jshint maxparams:4 */\nvar startPolling = function (method, id, callback, uninstall) {\n web3.manager.startPolling({\n method: method, \n params: [id]\n }, id, callback, uninstall); \n};\n/*jshint maxparams:3 */\n\nvar stopPolling = function (id) {\n web3.manager.stopPolling(id);\n};\n\nvar ethWatch = {\n startPolling: startPolling.bind(null, 'eth_getFilterChanges'), \n stopPolling: stopPolling\n};\n\nvar shhWatch = {\n startPolling: startPolling.bind(null, 'shh_getFilterChanges'), \n stopPolling: stopPolling\n};\n\n/// setups web3 object, and it's in-browser executed methods\nvar web3 = {\n\n version: {\n api: version.version\n },\n\n manager: requestManager(),\n providers: {},\n\n setProvider: function (provider) {\n web3.manager.setProvider(provider);\n },\n \n /// Should be called to reset state of web3 object\n /// Resets everything except manager\n reset: function () {\n web3.manager.reset(); \n },\n\n /// @returns hex string of the input\n toHex: utils.toHex,\n\n /// @returns ascii string representation of hex value prefixed with 0x\n toAscii: utils.toAscii,\n\n /// @returns hex representation (prefixed by 0x) of ascii string\n fromAscii: utils.fromAscii,\n\n /// @returns decimal representaton of hex value prefixed by 0x\n toDecimal: utils.toDecimal,\n\n /// @returns hex representation (prefixed by 0x) of decimal value\n fromDecimal: utils.fromDecimal,\n\n /// @returns a BigNumber object\n toBigNumber: utils.toBigNumber,\n\n toWei: utils.toWei,\n fromWei: utils.fromWei,\n isAddress: utils.isAddress,\n\n // provide network information\n net: {\n // peerCount: \n },\n\n\n /// eth object prototype\n eth: {\n // DEPRECATED\n contractFromAbi: function (abi) {\n console.warn('Initiating a contract like this is deprecated please use var MyContract = eth.contract(abi); new MyContract(address); instead.');\n\n return function(addr) {\n // Default to address of Config. TODO: rremove prior to genesis.\n addr = addr || '0xc6d9d2cd449a754c494264e1809c50e34d64562b';\n var ret = web3.eth.contract(addr, abi);\n ret.address = addr;\n return ret;\n };\n },\n\n /// @param filter may be a string, object or event\n /// @param eventParams is optional, this is an object with optional event eventParams params\n /// @param options is optional, this is an object with optional event options ('max'...)\n /*jshint maxparams:4 */\n filter: function (fil, eventParams, options) {\n\n // if its event, treat it differently\n if (fil._isEvent)\n return fil(eventParams, options);\n\n return filter(fil, ethWatch, formatters.outputLogFormatter);\n },\n // DEPRECATED\n watch: function (fil, eventParams, options) {\n console.warn('eth.watch() is deprecated please use eth.filter() instead.');\n return this.filter(fil, eventParams, options);\n }\n /*jshint maxparams:3 */\n },\n\n /// db object prototype\n db: {},\n\n /// shh object prototype\n shh: {\n /// @param filter may be a string, object or event\n filter: function (fil) {\n return filter(fil, shhWatch, formatters.outputPostFormatter);\n },\n // DEPRECATED\n watch: function (fil) {\n console.warn('shh.watch() is deprecated please use shh.filter() instead.');\n return this.filter(fil);\n }\n }\n};\n\n\n// ADD defaultblock\nObject.defineProperty(web3.eth, 'defaultBlock', {\n get: function () {\n return c.ETH_DEFAULTBLOCK;\n },\n set: function (val) {\n c.ETH_DEFAULTBLOCK = val;\n return c.ETH_DEFAULTBLOCK;\n }\n});\n\n\n/// setups all api methods\nsetupMethods(web3, web3Methods);\nsetupProperties(web3, web3Properties);\nsetupMethods(web3.net, net.methods);\nsetupProperties(web3.net, net.properties);\nsetupMethods(web3.eth, eth.methods);\nsetupProperties(web3.eth, eth.properties);\nsetupMethods(web3.db, db.methods());\nsetupMethods(web3.shh, shh.methods());\nsetupMethods(ethWatch, watches.eth());\nsetupMethods(shhWatch, watches.shh());\n\nmodule.exports = web3;\n\n", - "/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/** @file contract.js\n * @authors:\n * Marek Kotewicz \n * @date 2014\n */\n\nvar web3 = require('../web3'); \nvar abi = require('../solidity/abi');\nvar utils = require('../utils/utils');\nvar eventImpl = require('./event');\nvar signature = require('./signature');\n\nvar exportNatspecGlobals = function (vars) {\n // it's used byt natspec.js\n // TODO: figure out better way to solve this\n web3._currentContractAbi = vars.abi;\n web3._currentContractAddress = vars.address;\n web3._currentContractMethodName = vars.method;\n web3._currentContractMethodParams = vars.params;\n};\n\nvar addFunctionRelatedPropertiesToContract = function (contract) {\n \n contract.call = function (options) {\n contract._isTransaction = false;\n contract._options = options;\n return contract;\n };\n\n\n contract.sendTransaction = function (options) {\n contract._isTransaction = true;\n contract._options = options;\n return contract;\n };\n // DEPRECATED\n contract.transact = function (options) {\n\n console.warn('myContract.transact() is deprecated please use myContract.sendTransaction() instead.');\n\n return contract.sendTransaction(options);\n };\n\n contract._options = {};\n ['gas', 'gasPrice', 'value', 'from'].forEach(function(p) {\n contract[p] = function (v) {\n contract._options[p] = v;\n return contract;\n };\n });\n\n};\n\nvar addFunctionsToContract = function (contract, desc, address) {\n var inputParser = abi.inputParser(desc);\n var outputParser = abi.outputParser(desc);\n\n // create contract functions\n utils.filterFunctions(desc).forEach(function (method) {\n\n var displayName = utils.extractDisplayName(method.name);\n var typeName = utils.extractTypeName(method.name);\n\n var impl = function () {\n /*jshint maxcomplexity:7 */\n var params = Array.prototype.slice.call(arguments);\n var sign = signature.functionSignatureFromAscii(method.name);\n var parsed = inputParser[displayName][typeName].apply(null, params);\n\n var options = contract._options || {};\n options.to = address;\n options.data = sign + parsed;\n \n var isTransaction = contract._isTransaction === true || (contract._isTransaction !== false && !method.constant);\n var collapse = options.collapse !== false;\n \n // reset\n contract._options = {};\n contract._isTransaction = null;\n\n if (isTransaction) {\n \n exportNatspecGlobals({\n abi: desc,\n address: address,\n method: method.name,\n params: params\n });\n\n // transactions do not have any output, cause we do not know, when they will be processed\n web3.eth.sendTransaction(options);\n return;\n }\n \n var output = web3.eth.call(options);\n var ret = outputParser[displayName][typeName](output);\n if (collapse)\n {\n if (ret.length === 1)\n ret = ret[0];\n else if (ret.length === 0)\n ret = null;\n }\n return ret;\n };\n\n if (contract[displayName] === undefined) {\n contract[displayName] = impl;\n }\n\n contract[displayName][typeName] = impl;\n });\n};\n\nvar addEventRelatedPropertiesToContract = function (contract, desc, address) {\n contract.address = address;\n contract._onWatchEventResult = function (data) {\n var matchingEvent = event.getMatchingEvent(utils.filterEvents(desc));\n var parser = eventImpl.outputParser(matchingEvent);\n return parser(data);\n };\n \n Object.defineProperty(contract, 'topics', {\n get: function() {\n return utils.filterEvents(desc).map(function (e) {\n return signature.eventSignatureFromAscii(e.name);\n });\n }\n });\n\n};\n\nvar addEventsToContract = function (contract, desc, address) {\n // create contract events\n utils.filterEvents(desc).forEach(function (e) {\n\n var impl = function () {\n var params = Array.prototype.slice.call(arguments);\n var sign = signature.eventSignatureFromAscii(e.name);\n var event = eventImpl.inputParser(address, sign, e);\n var o = event.apply(null, params);\n var outputFormatter = function (data) {\n var parser = eventImpl.outputParser(e);\n return parser(data);\n };\n return web3.eth.filter(o, undefined, undefined, outputFormatter);\n };\n \n // this property should be used by eth.filter to check if object is an event\n impl._isEvent = true;\n\n var displayName = utils.extractDisplayName(e.name);\n var typeName = utils.extractTypeName(e.name);\n\n if (contract[displayName] === undefined) {\n contract[displayName] = impl;\n }\n\n contract[displayName][typeName] = impl;\n\n });\n};\n\n\n/**\n * This method should be called when we want to call / transact some solidity method from javascript\n * it returns an object which has same methods available as solidity contract description\n * usage example: \n *\n * var abi = [{\n * name: 'myMethod',\n * inputs: [{ name: 'a', type: 'string' }],\n * outputs: [{name: 'd', type: 'string' }]\n * }]; // contract abi\n *\n * var MyContract = web3.eth.contract(abi); // creation of contract prototype\n *\n * var contractInstance = new MyContract('0x0123123121');\n *\n * contractInstance.myMethod('this is test string param for call'); // myMethod call (implicit, default)\n * contractInstance.call().myMethod('this is test string param for call'); // myMethod call (explicit)\n * contractInstance.sendTransaction().myMethod('this is test string param for transact'); // myMethod sendTransaction\n *\n * @param abi - abi json description of the contract, which is being created\n * @returns contract object\n */\nvar contract = function (abi) {\n\n // return prototype\n if(abi instanceof Array && arguments.length === 1) {\n return Contract.bind(null, abi);\n\n // deprecated: auto initiate contract\n } else {\n\n console.warn('Initiating a contract like this is deprecated please use var MyContract = eth.contract(abi); new MyContract(address); instead.');\n\n return new Contract(arguments[1], arguments[0]);\n }\n\n};\n\nfunction Contract(abi, address) {\n\n // workaround for invalid assumption that method.name is the full anonymous prototype of the method.\n // it's not. it's just the name. the rest of the code assumes it's actually the anonymous\n // prototype, so we make it so as a workaround.\n // TODO: we may not want to modify input params, maybe use copy instead?\n abi.forEach(function (method) {\n if (method.name.indexOf('(') === -1) {\n var displayName = method.name;\n var typeName = method.inputs.map(function(i){return i.type; }).join();\n method.name = displayName + '(' + typeName + ')';\n }\n });\n\n var result = {};\n addFunctionRelatedPropertiesToContract(result);\n addFunctionsToContract(result, abi, address);\n addEventRelatedPropertiesToContract(result, abi, address);\n addEventsToContract(result, abi, address);\n\n return result;\n}\n\nmodule.exports = contract;\n\n", + "/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/** @file contract.js\n * @authors:\n * Marek Kotewicz \n * @date 2014\n */\n\nvar web3 = require('../web3'); \nvar abi = require('../solidity/abi');\nvar utils = require('../utils/utils');\nvar eventImpl = require('./event');\nvar signature = require('./signature');\n\nvar exportNatspecGlobals = function (vars) {\n // it's used byt natspec.js\n // TODO: figure out better way to solve this\n web3._currentContractAbi = vars.abi;\n web3._currentContractAddress = vars.address;\n web3._currentContractMethodName = vars.method;\n web3._currentContractMethodParams = vars.params;\n};\n\nvar addFunctionRelatedPropertiesToContract = function (contract) {\n \n contract.call = function (options) {\n contract._isTransaction = false;\n contract._options = options;\n return contract;\n };\n\n\n contract.sendTransaction = function (options) {\n contract._isTransaction = true;\n contract._options = options;\n return contract;\n };\n // DEPRECATED\n contract.transact = function (options) {\n\n console.warn('myContract.transact() is deprecated please use myContract.sendTransaction() instead.');\n\n return contract.sendTransaction(options);\n };\n\n contract._options = {};\n ['gas', 'gasPrice', 'value', 'from'].forEach(function(p) {\n contract[p] = function (v) {\n contract._options[p] = v;\n return contract;\n };\n });\n\n};\n\nvar addFunctionsToContract = function (contract, desc, address) {\n var inputParser = abi.inputParser(desc);\n var outputParser = abi.outputParser(desc);\n\n // create contract functions\n utils.filterFunctions(desc).forEach(function (method) {\n\n var displayName = utils.extractDisplayName(method.name);\n var typeName = utils.extractTypeName(method.name);\n\n var impl = function () {\n /*jshint maxcomplexity:7 */\n var params = Array.prototype.slice.call(arguments);\n var sign = signature.functionSignatureFromAscii(method.name);\n var parsed = inputParser[displayName][typeName].apply(null, params);\n\n var options = contract._options || {};\n options.to = address;\n options.data = sign + parsed;\n \n var isTransaction = contract._isTransaction === true || (contract._isTransaction !== false && !method.constant);\n var collapse = options.collapse !== false;\n \n // reset\n contract._options = {};\n contract._isTransaction = null;\n\n if (isTransaction) {\n \n exportNatspecGlobals({\n abi: desc,\n address: address,\n method: method.name,\n params: params\n });\n\n // transactions do not have any output, cause we do not know, when they will be processed\n web3.eth.sendTransaction(options);\n return;\n }\n \n var output = web3.eth.call(options);\n var ret = outputParser[displayName][typeName](output);\n if (collapse)\n {\n if (ret.length === 1)\n ret = ret[0];\n else if (ret.length === 0)\n ret = null;\n }\n return ret;\n };\n\n if (contract[displayName] === undefined) {\n contract[displayName] = impl;\n }\n\n contract[displayName][typeName] = impl;\n });\n};\n\nvar addEventRelatedPropertiesToContract = function (contract, desc, address) {\n contract.address = address;\n contract._onWatchEventResult = function (data) {\n var matchingEvent = event.getMatchingEvent(utils.filterEvents(desc));\n var parser = eventImpl.outputParser(matchingEvent);\n return parser(data);\n };\n \n Object.defineProperty(contract, 'topics', {\n get: function() {\n return utils.filterEvents(desc).map(function (e) {\n return signature.eventSignatureFromAscii(e.name);\n });\n }\n });\n\n};\n\nvar addEventsToContract = function (contract, desc, address) {\n // create contract events\n utils.filterEvents(desc).forEach(function (e) {\n\n var impl = function () {\n var params = Array.prototype.slice.call(arguments);\n var sign = signature.eventSignatureFromAscii(e.name);\n var event = eventImpl.inputParser(address, sign, e);\n var o = event.apply(null, params);\n var outputFormatter = function (data) {\n var parser = eventImpl.outputParser(e);\n return parser(data);\n };\n\t\t\treturn web3.eth.filter(o, undefined, undefined, outputFormatter);\n };\n \n // this property should be used by eth.filter to check if object is an event\n impl._isEvent = true;\n\n var displayName = utils.extractDisplayName(e.name);\n var typeName = utils.extractTypeName(e.name);\n\n if (contract[displayName] === undefined) {\n contract[displayName] = impl;\n }\n\n contract[displayName][typeName] = impl;\n\n });\n};\n\n\n/**\n * This method should be called when we want to call / transact some solidity method from javascript\n * it returns an object which has same methods available as solidity contract description\n * usage example: \n *\n * var abi = [{\n * name: 'myMethod',\n * inputs: [{ name: 'a', type: 'string' }],\n * outputs: [{name: 'd', type: 'string' }]\n * }]; // contract abi\n *\n * var MyContract = web3.eth.contract(abi); // creation of contract prototype\n *\n * var contractInstance = new MyContract('0x0123123121');\n *\n * contractInstance.myMethod('this is test string param for call'); // myMethod call (implicit, default)\n * contractInstance.call().myMethod('this is test string param for call'); // myMethod call (explicit)\n * contractInstance.sendTransaction().myMethod('this is test string param for transact'); // myMethod sendTransaction\n *\n * @param abi - abi json description of the contract, which is being created\n * @returns contract object\n */\nvar contract = function (abi) {\n\n // return prototype\n if(abi instanceof Array && arguments.length === 1) {\n return Contract.bind(null, abi);\n\n // deprecated: auto initiate contract\n } else {\n\n console.warn('Initiating a contract like this is deprecated please use var MyContract = eth.contract(abi); new MyContract(address); instead.');\n\n return new Contract(arguments[1], arguments[0]);\n }\n\n};\n\nfunction Contract(abi, address) {\n\n // workaround for invalid assumption that method.name is the full anonymous prototype of the method.\n // it's not. it's just the name. the rest of the code assumes it's actually the anonymous\n // prototype, so we make it so as a workaround.\n // TODO: we may not want to modify input params, maybe use copy instead?\n abi.forEach(function (method) {\n if (method.name.indexOf('(') === -1) {\n var displayName = method.name;\n var typeName = method.inputs.map(function(i){return i.type; }).join();\n method.name = displayName + '(' + typeName + ')';\n }\n });\n\n var result = {};\n addFunctionRelatedPropertiesToContract(result);\n addFunctionsToContract(result, abi, address);\n addEventRelatedPropertiesToContract(result, abi, address);\n addEventsToContract(result, abi, address);\n\n return result;\n}\n\nmodule.exports = contract;\n\n", "/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/** @file db.js\n * @authors:\n * Marek Kotewicz \n * @date 2015\n */\n\n\n/// @returns an array of objects describing web3.db api methods\nvar methods = function () {\n return [\n { name: 'putString', call: 'db_putString'},\n { name: 'getString', call: 'db_getString'},\n { name: 'putHex', call: 'db_putHex'},\n { name: 'getHex', call: 'db_getHex'}\n ];\n};\n\nmodule.exports = {\n methods: methods\n};\n", - "/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/** @file eth.js\n * @authors:\n * Marek Kotewicz \n * Fabian Vogelsteller \n * @date 2015\n */\n\n/**\n * Web3\n * \n * @module web3\n */\n\n/**\n * Eth methods and properties\n *\n * An example method object can look as follows:\n *\n * {\n * name: 'getBlock',\n * call: blockCall,\n * outputFormatter: formatters.outputBlockFormatter,\n * inputFormatter: [ // can be a formatter funciton or an array of functions. Where each item in the array will be used for one parameter\n * utils.toHex, // formats paramter 1\n * function(param){ if(!param) return false; } // formats paramter 2\n * ]\n * },\n *\n * @class [web3] eth\n * @constructor\n */\n\n\nvar formatters = require('./formatters');\nvar utils = require('../utils/utils');\n\n\nvar blockCall = function (args) {\n return (utils.isString(args[0]) && args[0].indexOf('0x') === 0) ? \"eth_getBlockByHash\" : \"eth_getBlockByNumber\";\n};\n\nvar transactionFromBlockCall = function (args) {\n return (utils.isString(args[0]) && args[0].indexOf('0x') === 0) ? 'eth_getTransactionByBlockHashAndIndex' : 'eth_getTransactionByBlockNumberAndIndex';\n};\n\nvar uncleCall = function (args) {\n return (utils.isString(args[0]) && args[0].indexOf('0x') === 0) ? 'eth_getUncleByBlockHashAndIndex' : 'eth_getUncleByBlockNumberAndIndex';\n};\n\nvar getBlockTransactionCountCall = function (args) {\n return (utils.isString(args[0]) && args[0].indexOf('0x') === 0) ? 'eth_getBlockTransactionCountByHash' : 'eth_getBlockTransactionCountByNumber';\n};\n\nvar uncleCountCall = function (args) {\n return (utils.isString(args[0]) && args[0].indexOf('0x') === 0) ? 'eth_getUncleCountByBlockHash' : 'eth_getUncleCountByBlockNumber';\n};\n\n/// @returns an array of objects describing web3.eth api methods\nvar methods = [\n { name: 'getBalance', call: 'eth_getBalance', addDefaultblock: 2,\n outputFormatter: formatters.convertToBigNumber},\n { name: 'getStorage', call: 'eth_getStorage', addDefaultblock: 2},\n { name: 'getStorageAt', call: 'eth_getStorageAt', addDefaultblock: 3,\n inputFormatter: utils.toHex},\n { name: 'getData', call: 'eth_getData', addDefaultblock: 2},\n { name: 'getBlock', call: blockCall,\n outputFormatter: formatters.outputBlockFormatter,\n inputFormatter: [utils.toHex, function(param){ return (!param) ? false : true; }]},\n { name: 'getUncle', call: uncleCall,\n outputFormatter: formatters.outputBlockFormatter,\n inputFormatter: [utils.toHex, utils.toHex, function(param){ return (!param) ? false : true; }]},\n { name: 'getCompilers', call: 'eth_getCompilers' },\n { name: 'getBlockTransactionCount', call: getBlockTransactionCountCall,\n outputFormatter: utils.toDecimal,\n inputFormatter: utils.toHex },\n { name: 'getBlockUncleCount', call: uncleCountCall,\n outputFormatter: utils.toDecimal,\n inputFormatter: utils.toHex },\n { name: 'getTransaction', call: 'eth_getTransactionByHash',\n outputFormatter: formatters.outputTransactionFormatter },\n { name: 'getTransactionFromBlock', call: transactionFromBlockCall,\n outputFormatter: formatters.outputTransactionFormatter,\n inputFormatter: utils.toHex },\n { name: 'getTransactionCount', call: 'eth_getTransactionCount', addDefaultblock: 2,\n outputFormatter: utils.toDecimal},\n { name: 'sendTransaction', call: 'eth_sendTransaction',\n inputFormatter: formatters.inputTransactionFormatter },\n { name: 'call', call: 'eth_call', addDefaultblock: 2,\n inputFormatter: formatters.inputCallFormatter },\n { name: 'compile.solidity', call: 'eth_compileSolidity' },\n { name: 'compile.lll', call: 'eth_compileLLL', inputFormatter: utils.toHex },\n { name: 'compile.serpent', call: 'eth_compileSerpent', inputFormatter: utils.toHex },\n { name: 'flush', call: 'eth_flush' },\n\n // deprecated methods\n { name: 'balanceAt', call: 'eth_balanceAt', newMethod: 'eth.getBalance' },\n { name: 'stateAt', call: 'eth_stateAt', newMethod: 'eth.getStorageAt' },\n { name: 'storageAt', call: 'eth_storageAt', newMethod: 'eth.getStorage' },\n { name: 'countAt', call: 'eth_countAt', newMethod: 'eth.getTransactionCount' },\n { name: 'codeAt', call: 'eth_codeAt', newMethod: 'eth.getData' },\n { name: 'transact', call: 'eth_transact', newMethod: 'eth.sendTransaction' },\n { name: 'block', call: blockCall, newMethod: 'eth.getBlock' },\n { name: 'transaction', call: transactionFromBlockCall, newMethod: 'eth.getTransaction' },\n { name: 'uncle', call: uncleCall, newMethod: 'eth.getUncle' },\n { name: 'compilers', call: 'eth_compilers', newMethod: 'eth.getCompilers' },\n { name: 'solidity', call: 'eth_solidity', newMethod: 'eth.compile.solidity' },\n { name: 'lll', call: 'eth_lll', newMethod: 'eth.compile.lll' },\n { name: 'serpent', call: 'eth_serpent', newMethod: 'eth.compile.serpent' },\n { name: 'transactionCount', call: getBlockTransactionCountCall, newMethod: 'eth.getBlockTransactionCount' },\n { name: 'uncleCount', call: uncleCountCall, newMethod: 'eth.getBlockUncleCount' },\n { name: 'logs', call: 'eth_logs' }\n];\n\n/// @returns an array of objects describing web3.eth api properties\nvar properties = [\n { name: 'coinbase', getter: 'eth_coinbase'},\n { name: 'mining', getter: 'eth_mining'},\n { name: 'gasPrice', getter: 'eth_gasPrice', outputFormatter: formatters.convertToBigNumber},\n { name: 'accounts', getter: 'eth_accounts' },\n { name: 'blockNumber', getter: 'eth_blockNumber', outputFormatter: utils.toDecimal},\n\n // deprecated properties\n { name: 'listening', getter: 'net_listening', setter: 'eth_setListening', newProperty: 'net.listening'},\n { name: 'peerCount', getter: 'net_peerCount', newProperty: 'net.peerCount'},\n { name: 'number', getter: 'eth_number', newProperty: 'eth.blockNumber'}\n];\n\n\nmodule.exports = {\n methods: methods,\n properties: properties\n};\n\n", + "/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/** @file eth.js\n * @authors:\n * Marek Kotewicz \n * Fabian Vogelsteller \n * @date 2015\n */\n\n/**\n * Web3\n * \n * @module web3\n */\n\n/**\n * Eth methods and properties\n *\n * An example method object can look as follows:\n *\n * {\n * name: 'getBlock',\n * call: blockCall,\n * outputFormatter: formatters.outputBlockFormatter,\n * inputFormatter: [ // can be a formatter funciton or an array of functions. Where each item in the array will be used for one parameter\n * utils.toHex, // formats paramter 1\n * function(param){ if(!param) return false; } // formats paramter 2\n * ]\n * },\n *\n * @class [web3] eth\n * @constructor\n */\n\n\nvar formatters = require('./formatters');\nvar utils = require('../utils/utils');\n\n\nvar blockCall = function (args) {\n return (utils.isString(args[0]) && args[0].indexOf('0x') === 0) ? \"eth_getBlockByHash\" : \"eth_getBlockByNumber\";\n};\n\nvar transactionFromBlockCall = function (args) {\n return (utils.isString(args[0]) && args[0].indexOf('0x') === 0) ? 'eth_getTransactionByBlockHashAndIndex' : 'eth_getTransactionByBlockNumberAndIndex';\n};\n\nvar uncleCall = function (args) {\n return (utils.isString(args[0]) && args[0].indexOf('0x') === 0) ? 'eth_getUncleByBlockHashAndIndex' : 'eth_getUncleByBlockNumberAndIndex';\n};\n\nvar getBlockTransactionCountCall = function (args) {\n return (utils.isString(args[0]) && args[0].indexOf('0x') === 0) ? 'eth_getBlockTransactionCountByHash' : 'eth_getBlockTransactionCountByNumber';\n};\n\nvar uncleCountCall = function (args) {\n return (utils.isString(args[0]) && args[0].indexOf('0x') === 0) ? 'eth_getUncleCountByBlockHash' : 'eth_getUncleCountByBlockNumber';\n};\n\n/// @returns an array of objects describing web3.eth api methods\nvar methods = [\n { name: 'getBalance', call: 'eth_getBalance', addDefaultblock: 2,\n outputFormatter: formatters.convertToBigNumber},\n { name: 'getStorageAt', call: 'eth_getStorageAt', addDefaultblock: 3,\n inputFormatter: utils.toHex},\n\t{ name: 'getCode', call: 'eth_getCode', addDefaultblock: 2},\n { name: 'getBlock', call: blockCall,\n outputFormatter: formatters.outputBlockFormatter,\n inputFormatter: [utils.toHex, function(param){ return (!param) ? false : true; }]},\n { name: 'getUncle', call: uncleCall,\n outputFormatter: formatters.outputBlockFormatter,\n inputFormatter: [utils.toHex, utils.toHex, function(param){ return (!param) ? false : true; }]},\n { name: 'getCompilers', call: 'eth_getCompilers' },\n { name: 'getBlockTransactionCount', call: getBlockTransactionCountCall,\n outputFormatter: utils.toDecimal,\n inputFormatter: utils.toHex },\n { name: 'getBlockUncleCount', call: uncleCountCall,\n outputFormatter: utils.toDecimal,\n inputFormatter: utils.toHex },\n { name: 'getTransaction', call: 'eth_getTransactionByHash',\n outputFormatter: formatters.outputTransactionFormatter },\n { name: 'getTransactionFromBlock', call: transactionFromBlockCall,\n outputFormatter: formatters.outputTransactionFormatter,\n inputFormatter: utils.toHex },\n { name: 'getTransactionCount', call: 'eth_getTransactionCount', addDefaultblock: 2,\n outputFormatter: utils.toDecimal},\n { name: 'sendTransaction', call: 'eth_sendTransaction',\n inputFormatter: formatters.inputTransactionFormatter },\n { name: 'call', call: 'eth_call', addDefaultblock: 2,\n inputFormatter: formatters.inputCallFormatter },\n { name: 'compile.solidity', call: 'eth_compileSolidity' },\n { name: 'compile.lll', call: 'eth_compileLLL', inputFormatter: utils.toHex },\n { name: 'compile.serpent', call: 'eth_compileSerpent', inputFormatter: utils.toHex },\n { name: 'flush', call: 'eth_flush' },\n\n // deprecated methods\n { name: 'balanceAt', call: 'eth_balanceAt', newMethod: 'eth.getBalance' },\n { name: 'stateAt', call: 'eth_stateAt', newMethod: 'eth.getStorageAt' },\n { name: 'storageAt', call: 'eth_storageAt', newMethod: 'eth.getStorage' },\n { name: 'countAt', call: 'eth_countAt', newMethod: 'eth.getTransactionCount' },\n\t{ name: 'codeAt', call: 'eth_codeAt', newMethod: 'eth.getCode' },\n { name: 'transact', call: 'eth_transact', newMethod: 'eth.sendTransaction' },\n { name: 'block', call: blockCall, newMethod: 'eth.getBlock' },\n { name: 'transaction', call: transactionFromBlockCall, newMethod: 'eth.getTransaction' },\n { name: 'uncle', call: uncleCall, newMethod: 'eth.getUncle' },\n { name: 'compilers', call: 'eth_compilers', newMethod: 'eth.getCompilers' },\n { name: 'solidity', call: 'eth_solidity', newMethod: 'eth.compile.solidity' },\n { name: 'lll', call: 'eth_lll', newMethod: 'eth.compile.lll' },\n { name: 'serpent', call: 'eth_serpent', newMethod: 'eth.compile.serpent' },\n { name: 'transactionCount', call: getBlockTransactionCountCall, newMethod: 'eth.getBlockTransactionCount' },\n { name: 'uncleCount', call: uncleCountCall, newMethod: 'eth.getBlockUncleCount' },\n { name: 'logs', call: 'eth_logs' }\n];\n\n/// @returns an array of objects describing web3.eth api properties\nvar properties = [\n { name: 'coinbase', getter: 'eth_coinbase'},\n { name: 'mining', getter: 'eth_mining'},\n { name: 'gasPrice', getter: 'eth_gasPrice', outputFormatter: formatters.convertToBigNumber},\n { name: 'accounts', getter: 'eth_accounts' },\n { name: 'blockNumber', getter: 'eth_blockNumber', outputFormatter: utils.toDecimal},\n\n // deprecated properties\n { name: 'listening', getter: 'net_listening', setter: 'eth_setListening', newProperty: 'net.listening'},\n { name: 'peerCount', getter: 'net_peerCount', newProperty: 'net.peerCount'},\n { name: 'number', getter: 'eth_number', newProperty: 'eth.blockNumber'}\n];\n\n\nmodule.exports = {\n methods: methods,\n properties: properties\n};\n\n", "/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/** @file event.js\n * @authors:\n * Marek Kotewicz \n * @date 2014\n */\n\nvar abi = require('../solidity/abi');\nvar utils = require('../utils/utils');\nvar signature = require('./signature');\n\n/// filter inputs array && returns only indexed (or not) inputs\n/// @param inputs array\n/// @param bool if result should be an array of indexed params on not\n/// @returns array of (not?) indexed params\nvar filterInputs = function (inputs, indexed) {\n return inputs.filter(function (current) {\n return current.indexed === indexed;\n });\n};\n\nvar inputWithName = function (inputs, name) {\n var index = utils.findIndex(inputs, function (input) {\n return input.name === name;\n });\n \n if (index === -1) {\n console.error('indexed param with name ' + name + ' not found');\n return undefined;\n }\n return inputs[index];\n};\n\nvar indexedParamsToTopics = function (event, indexed) {\n // sort keys?\n return Object.keys(indexed).map(function (key) {\n var inputs = [inputWithName(filterInputs(event.inputs, true), key)];\n\n var value = indexed[key];\n if (value instanceof Array) {\n return value.map(function (v) {\n return abi.formatInput(inputs, [v]);\n }); \n }\n return abi.formatInput(inputs, [value]);\n });\n};\n\nvar inputParser = function (address, sign, event) {\n \n // valid options are 'earliest', 'latest', 'offset' and 'max', as defined for 'eth.filter'\n return function (indexed, options) {\n var o = options || {};\n o.address = address;\n o.topics = [];\n o.topics.push(sign);\n if (indexed) {\n o.topics = o.topics.concat(indexedParamsToTopics(event, indexed));\n }\n return o;\n };\n};\n\nvar getArgumentsObject = function (inputs, indexed, notIndexed) {\n var indexedCopy = indexed.slice();\n var notIndexedCopy = notIndexed.slice();\n return inputs.reduce(function (acc, current) {\n var value;\n if (current.indexed)\n value = indexedCopy.splice(0, 1)[0];\n else\n value = notIndexedCopy.splice(0, 1)[0];\n\n acc[current.name] = value;\n return acc;\n }, {}); \n};\n \nvar outputParser = function (event) {\n \n return function (output) {\n var result = {\n event: utils.extractDisplayName(event.name),\n number: output.number,\n hash: output.hash,\n args: {}\n };\n\n output.topics = output.topic; // fallback for go-ethereum\n if (!output.topics) {\n return result;\n }\n \n var indexedOutputs = filterInputs(event.inputs, true);\n var indexedData = \"0x\" + output.topics.slice(1, output.topics.length).map(function (topics) { return topics.slice(2); }).join(\"\");\n var indexedRes = abi.formatOutput(indexedOutputs, indexedData);\n\n var notIndexedOutputs = filterInputs(event.inputs, false);\n var notIndexedRes = abi.formatOutput(notIndexedOutputs, output.data);\n\n result.args = getArgumentsObject(event.inputs, indexedRes, notIndexedRes);\n\n return result;\n };\n};\n\nvar getMatchingEvent = function (events, payload) {\n for (var i = 0; i < events.length; i++) {\n var sign = signature.eventSignatureFromAscii(events[i].name); \n if (sign === payload.topics[0]) {\n return events[i];\n }\n }\n return undefined;\n};\n\n\nmodule.exports = {\n inputParser: inputParser,\n outputParser: outputParser,\n getMatchingEvent: getMatchingEvent\n};\n\n", - "/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/** @file filter.js\n * @authors:\n * Jeffrey Wilcke \n * Marek Kotewicz \n * Marian Oancea \n * Fabian Vogelsteller \n * Gav Wood \n * @date 2014\n */\n\nvar utils = require('../utils/utils');\n\n/// Should be called to check if filter implementation is valid\n/// @returns true if it is, otherwise false\nvar implementationIsValid = function (i) {\n return !!i && \n typeof i.newFilter === 'function' && \n typeof i.getLogs === 'function' && \n typeof i.uninstallFilter === 'function' &&\n typeof i.startPolling === 'function' &&\n typeof i.stopPolling === 'function';\n};\n\n/// This method should be called on options object, to verify deprecated properties && lazy load dynamic ones\n/// @param should be string or object\n/// @returns options string or object\nvar getOptions = function (options) {\n /*jshint maxcomplexity:9 */\n\n if (typeof options === 'string') {\n return options;\n } \n\n options = options || {};\n\n if (options.topic) {\n console.warn('\"topic\" is deprecated, is \"topics\" instead');\n options.topics = options.topic;\n }\n\n if (options.earliest) {\n console.warn('\"earliest\" is deprecated, is \"fromBlock\" instead');\n options.fromBlock = options.earliest;\n }\n\n if (options.latest) {\n console.warn('\"latest\" is deprecated, is \"toBlock\" instead');\n options.toBlock = options.latest;\n }\n\n if (options.skip) {\n console.warn('\"skip\" is deprecated, is \"offset\" instead');\n options.offset = options.skip;\n }\n\n if (options.max) {\n console.warn('\"max\" is deprecated, is \"limit\" instead');\n options.limit = options.max;\n }\n\n // make sure topics, get converted to hex\n if(options.topics instanceof Array) {\n options.topics = options.topics.map(function(topic){\n return utils.toHex(topic);\n });\n }\n\n\n // evaluate lazy properties\n return {\n fromBlock: utils.toHex(options.fromBlock),\n toBlock: utils.toHex(options.toBlock),\n limit: utils.toHex(options.limit),\n offset: utils.toHex(options.offset),\n to: options.to,\n address: options.address,\n topics: options.topics\n };\n};\n\n/// Should be used when we want to watch something\n/// it's using inner polling mechanism and is notified about changes\n/// @param options are filter options\n/// @param implementation, an abstract polling implementation\n/// @param formatter (optional), callback function which formats output before 'real' callback \nvar filter = function(options, implementation, formatter) {\n if (!implementationIsValid(implementation)) {\n console.error('filter implemenation is invalid');\n return;\n }\n\n options = getOptions(options);\n var callbacks = [];\n var filterId = implementation.newFilter(options);\n\n // call the callbacks\n var onMessages = function (messages) {\n messages.forEach(function (message) {\n message = formatter ? formatter(message) : message;\n callbacks.forEach(function (callback) {\n callback(message);\n });\n });\n };\n\n implementation.startPolling(filterId, onMessages, implementation.uninstallFilter);\n\n var watch = function(callback) {\n callbacks.push(callback);\n };\n\n var stopWatching = function() {\n implementation.stopPolling(filterId);\n implementation.uninstallFilter(filterId);\n callbacks = [];\n };\n\n var get = function () {\n var results = implementation.getLogs(filterId);\n\n return utils.isArray(results) ? results.map(function(message){\n return formatter ? formatter(message) : message;\n }) : results;\n };\n \n return {\n watch: watch,\n stopWatching: stopWatching,\n get: get,\n\n // DEPRECATED methods\n changed: function(){\n console.warn('watch().changed() is deprecated please use filter().watch() instead.');\n return watch.apply(this, arguments);\n },\n arrived: function(){\n console.warn('watch().arrived() is deprecated please use filter().watch() instead.');\n return watch.apply(this, arguments);\n },\n happened: function(){\n console.warn('watch().happened() is deprecated please use filter().watch() instead.');\n return watch.apply(this, arguments);\n },\n uninstall: function(){\n console.warn('watch().uninstall() is deprecated please use filter().stopWatching() instead.');\n return stopWatching.apply(this, arguments);\n },\n messages: function(){\n console.warn('watch().messages() is deprecated please use filter().get() instead.');\n return get.apply(this, arguments);\n },\n logs: function(){\n console.warn('watch().logs() is deprecated please use filter().get() instead.');\n return get.apply(this, arguments);\n }\n };\n};\n\nmodule.exports = filter;\n\n", + "/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/** @file filter.js\n * @authors:\n * Jeffrey Wilcke \n * Marek Kotewicz \n * Marian Oancea \n * Fabian Vogelsteller \n * Gav Wood \n * @date 2014\n */\n\nvar utils = require('../utils/utils');\n\n/// Should be called to check if filter implementation is valid\n/// @returns true if it is, otherwise false\nvar implementationIsValid = function (i) {\n return !!i && \n typeof i.newFilter === 'function' && \n typeof i.getLogs === 'function' && \n typeof i.uninstallFilter === 'function' &&\n typeof i.startPolling === 'function' &&\n typeof i.stopPolling === 'function';\n};\n\n/// This method should be called on options object, to verify deprecated properties && lazy load dynamic ones\n/// @param should be string or object\n/// @returns options string or object\nvar getOptions = function (options) {\n /*jshint maxcomplexity:9 */\n\n if (typeof options === 'string') {\n return options;\n } \n\n options = options || {};\n\n if (options.topic) {\n console.warn('\"topic\" is deprecated, is \"topics\" instead');\n options.topics = options.topic;\n }\n\n if (options.earliest) {\n console.warn('\"earliest\" is deprecated, is \"fromBlock\" instead');\n options.fromBlock = options.earliest;\n }\n\n if (options.latest) {\n console.warn('\"latest\" is deprecated, is \"toBlock\" instead');\n options.toBlock = options.latest;\n }\n\n // make sure topics, get converted to hex\n if(options.topics instanceof Array) {\n options.topics = options.topics.map(function(topic){\n return utils.toHex(topic);\n });\n }\n\n\tvar asBlockNumber = function(n) {\n\t\tif (n == null)\n\t\t\treturn null;\n\t\tif (n == 'latest' || n == 'pending')\n\t\t\treturn n;\n\t\treturn utils.toHex(n);\n\t};\n\n // evaluate lazy properties\n return {\n\t\tfromBlock: asBlockNumber(options.fromBlock),\n\t\ttoBlock: asBlockNumber(options.toBlock),\n to: options.to,\n address: options.address,\n topics: options.topics\n };\n};\n\n/// Should be used when we want to watch something\n/// it's using inner polling mechanism and is notified about changes\n/// @param options are filter options\n/// @param implementation, an abstract polling implementation\n/// @param formatter (optional), callback function which formats output before 'real' callback \nvar filter = function(options, implementation, formatter) {\n if (!implementationIsValid(implementation)) {\n console.error('filter implemenation is invalid');\n return;\n }\n\n options = getOptions(options);\n var callbacks = [];\n var filterId = implementation.newFilter(options);\n\n // call the callbacks\n var onMessages = function (messages) {\n messages.forEach(function (message) {\n\t\t\tconsole.log(\"Got message: \" + JSON.stringify(message));\n\t\t\tmessage = formatter ? formatter(message) : message;\n callbacks.forEach(function (callback) {\n\t\t\t\tcallback(message);\n });\n });\n };\n\n implementation.startPolling(filterId, onMessages, implementation.uninstallFilter);\n\n var watch = function(callback) {\n callbacks.push(callback);\n };\n\n var stopWatching = function() {\n implementation.stopPolling(filterId);\n implementation.uninstallFilter(filterId);\n callbacks = [];\n };\n\n var get = function () {\n var results = implementation.getLogs(filterId);\n\n return utils.isArray(results) ? results.map(function(message){\n return formatter ? formatter(message) : message;\n }) : results;\n };\n \n return {\n watch: watch,\n stopWatching: stopWatching,\n get: get,\n\n // DEPRECATED methods\n changed: function(){\n console.warn('watch().changed() is deprecated please use filter().watch() instead.');\n return watch.apply(this, arguments);\n },\n arrived: function(){\n console.warn('watch().arrived() is deprecated please use filter().watch() instead.');\n return watch.apply(this, arguments);\n },\n happened: function(){\n console.warn('watch().happened() is deprecated please use filter().watch() instead.');\n return watch.apply(this, arguments);\n },\n uninstall: function(){\n console.warn('watch().uninstall() is deprecated please use filter().stopWatching() instead.');\n return stopWatching.apply(this, arguments);\n },\n messages: function(){\n console.warn('watch().messages() is deprecated please use filter().get() instead.');\n return get.apply(this, arguments);\n },\n logs: function(){\n console.warn('watch().logs() is deprecated please use filter().get() instead.');\n return get.apply(this, arguments);\n }\n };\n};\n\nmodule.exports = filter;\n\n", "/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/** @file formatters.js\n * @authors:\n * Marek Kotewicz \n * Fabian Vogelsteller \n * @date 2015\n */\n\nvar utils = require('../utils/utils');\n\n/**\n * Should the input to a big number\n *\n * @method convertToBigNumber\n * @param {String|Number|BigNumber}\n * @returns {BigNumber} object\n */\nvar convertToBigNumber = function (value) {\n return utils.toBigNumber(value);\n};\n\n/**\n * Formats the input of a transaction and converts all values to HEX\n *\n * @method inputTransactionFormatter\n * @param {Object} transaction options\n * @returns object\n*/\nvar inputTransactionFormatter = function (options){\n\n // make code -> data\n if (options.code) {\n options.data = options.code;\n delete options.code;\n }\n\n ['gasPrice', 'gas', 'value'].forEach(function(key){\n options[key] = utils.fromDecimal(options[key]);\n });\n\n return options;\n};\n\n/**\n * Formats the output of a transaction to its proper values\n * \n * @method outputTransactionFormatter\n * @param {Object} transaction\n * @returns {Object} transaction\n*/\nvar outputTransactionFormatter = function (tx){\n tx.gas = utils.toDecimal(tx.gas);\n tx.gasPrice = utils.toBigNumber(tx.gasPrice);\n tx.value = utils.toBigNumber(tx.value);\n return tx;\n};\n\n/**\n * Formats the input of a call and converts all values to HEX\n *\n * @method inputCallFormatter\n * @param {Object} transaction options\n * @returns object\n*/\nvar inputCallFormatter = function (options){\n\n // make code -> data\n if (options.code) {\n options.data = options.code;\n delete options.code;\n }\n\n return options;\n};\n\n\n/**\n * Formats the output of a block to its proper values\n *\n * @method outputBlockFormatter\n * @param {Object} block object \n * @returns {Object} block object\n*/\nvar outputBlockFormatter = function(block){\n\n // transform to number\n block.gasLimit = utils.toDecimal(block.gasLimit);\n block.gasUsed = utils.toDecimal(block.gasUsed);\n block.size = utils.toDecimal(block.size);\n block.timestamp = utils.toDecimal(block.timestamp);\n block.number = utils.toDecimal(block.number);\n\n block.minGasPrice = utils.toBigNumber(block.minGasPrice);\n block.difficulty = utils.toBigNumber(block.difficulty);\n block.totalDifficulty = utils.toBigNumber(block.totalDifficulty);\n\n if(block.transactions instanceof Array) {\n block.transactions.forEach(function(item){\n if(!utils.isString(item))\n return outputTransactionFormatter(item);\n });\n }\n\n return block;\n};\n\n/**\n * Formats the output of a log\n * \n * @method outputLogFormatter\n * @param {Object} log object\n * @returns {Object} log\n*/\nvar outputLogFormatter = function(log){\n log.blockNumber = utils.toDecimal(log.blockNumber);\n log.transactionIndex = utils.toDecimal(log.transactionIndex);\n log.logIndex = utils.toDecimal(log.logIndex);\n\n return log;\n};\n\n\n/**\n * Formats the input of a whisper post and converts all values to HEX\n *\n * @method inputPostFormatter\n * @param {Object} transaction object\n * @returns {Object}\n*/\nvar inputPostFormatter = function(post){\n\n post.payload = utils.toHex(post.payload);\n post.ttl = utils.fromDecimal(post.ttl);\n post.priority = utils.fromDecimal(post.priority);\n\n if(!(post.topics instanceof Array))\n post.topics = [post.topics];\n\n\n // format the following options\n post.topics = post.topics.map(function(topic){\n return utils.fromAscii(topic);\n });\n\n return post;\n};\n\n/**\n * Formats the output of a received post message\n *\n * @method outputPostFormatter\n * @param {Object}\n * @returns {Object}\n */\nvar outputPostFormatter = function(post){\n\n post.expiry = utils.toDecimal(post.expiry);\n post.sent = utils.toDecimal(post.sent);\n post.ttl = utils.toDecimal(post.ttl);\n post.workProved = utils.toDecimal(post.workProved);\n post.payloadRaw = post.payload;\n post.payload = utils.toAscii(post.payload);\n\n if(post.payload.indexOf('{') === 0 || post.payload.indexOf('[') === 0) {\n try {\n post.payload = JSON.parse(post.payload);\n } catch (e) { }\n }\n\n // format the following options\n post.topics = post.topics.map(function(topic){\n return utils.toAscii(topic);\n });\n\n return post;\n};\n\nmodule.exports = {\n convertToBigNumber: convertToBigNumber,\n inputTransactionFormatter: inputTransactionFormatter,\n outputTransactionFormatter: outputTransactionFormatter,\n inputCallFormatter: inputCallFormatter,\n outputBlockFormatter: outputBlockFormatter,\n outputLogFormatter: outputLogFormatter,\n inputPostFormatter: inputPostFormatter,\n outputPostFormatter: outputPostFormatter\n};\n\n", "/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/** @file httpprovider.js\n * @authors:\n * Marek Kotewicz \n * Marian Oancea \n * Fabian Vogelsteller \n * @date 2014\n */\n\nif (\"build\" !== 'build') {/*\n var XMLHttpRequest = require('xmlhttprequest').XMLHttpRequest; // jshint ignore:line\n*/}\n\nvar HttpProvider = function (host) {\n this.name = 'HTTP';\n this.handlers = [];\n this.host = host || 'http://localhost:8080';\n};\n\nHttpProvider.prototype.send = function (payload, callback) {\n var request = new XMLHttpRequest();\n\n // ASYNC\n if(typeof callback === 'function') {\n request.onreadystatechange = function() {\n if(request.readyState === 4) {\n var result = '';\n try {\n result = JSON.parse(request.responseText);\n } catch(error) {\n result = error;\n }\n callback(result, request.status);\n }\n };\n\n request.open('POST', this.host, true);\n request.send(JSON.stringify(payload));\n\n // SYNC\n } else {\n request.open('POST', this.host, false);\n request.send(JSON.stringify(payload));\n\n // check request.status\n if(request.status !== 200)\n return;\n return JSON.parse(request.responseText);\n \n }\n};\n\nmodule.exports = HttpProvider;\n\n", "/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/** @file jsonrpc.js\n * @authors:\n * Marek Kotewicz \n * @date 2015\n */\n\nvar messageId = 1;\n\n/// Should be called to valid json create payload object\n/// @param method of jsonrpc call, required\n/// @param params, an array of method params, optional\n/// @returns valid jsonrpc payload object\nvar toPayload = function (method, params) {\n if (!method)\n console.error('jsonrpc method should be specified!');\n\n return {\n jsonrpc: '2.0',\n method: method,\n params: params || [],\n id: messageId++\n }; \n};\n\n/// Should be called to check if jsonrpc response is valid\n/// @returns true if response is valid, otherwise false \nvar isValidResponse = function (response) {\n return !!response &&\n !response.error &&\n response.jsonrpc === '2.0' &&\n typeof response.id === 'number' &&\n response.result !== undefined; // only undefined is not valid json object\n};\n\n/// Should be called to create batch payload object\n/// @param messages, an array of objects with method (required) and params (optional) fields\nvar toBatchPayload = function (messages) {\n return messages.map(function (message) {\n return toPayload(message.method, message.params);\n }); \n};\n\nmodule.exports = {\n toPayload: toPayload,\n isValidResponse: isValidResponse,\n toBatchPayload: toBatchPayload\n};\n\n\n", diff --git a/libjsqrc/ethereumjs/dist/ethereum.min.js b/libjsqrc/ethereumjs/dist/ethereum.min.js index e0cb5a491..fd56cc979 100644 --- a/libjsqrc/ethereumjs/dist/ethereum.min.js +++ b/libjsqrc/ethereumjs/dist/ethereum.min.js @@ -1 +1 @@ -require=function t(e,n,r){function o(a,u){if(!n[a]){if(!e[a]){var s="function"==typeof require&&require;if(!u&&s)return s(a,!0);if(i)return i(a,!0);var c=new Error("Cannot find module '"+a+"'");throw c.code="MODULE_NOT_FOUND",c}var l=n[a]={exports:{}};e[a][0].call(l.exports,function(t){var n=e[a][1][t];return o(n?n:t)},l,l.exports,t,e,n,r)}return n[a].exports}for(var i="function"==typeof require&&require,a=0;ay;y++)g.push(d(e.slice(0,s))),e=e.slice(s);n.push(g)}else o.prefixedType("bytes")(t[c].type)?(l=l.slice(s),n.push(d(e.slice(0,s))),e=e.slice(s)):(n.push(d(e.slice(0,s))),e=e.slice(s))}),n},d=function(t){var e={};return t.forEach(function(t){var r=n.extractDisplayName(t.name),o=n.extractTypeName(t.name),i=function(){var e=Array.prototype.slice.call(arguments);return l(t.inputs,e)};void 0===e[r]&&(e[r]=i),e[r][o]=i}),e},h=function(t){var e={};return t.forEach(function(t){var r=n.extractDisplayName(t.name),o=n.extractTypeName(t.name),i=function(e){return m(t.outputs,e)};void 0===e[r]&&(e[r]=i),e[r][o]=i}),e};e.exports={inputParser:d,outputParser:h,formatInput:l,formatOutput:m}},{"../utils/config":4,"../utils/utils":5,"./formatters":2,"./types":3}],2:[function(t,e){var n=t("../utils/utils"),r=t("../utils/config"),o=function(t,e,n){return new Array(e-t.length+1).join(n?n:"0")+t},i=function(t){var e=2*r.ETH_PADDING;return BigNumber.config(r.ETH_BIGNUMBER_ROUNDING_MODE),o(n.toTwosComplement(t).round().toString(16),e)},a=function(t){return n.fromAscii(t,r.ETH_PADDING).substr(2)},u=function(t){return"000000000000000000000000000000000000000000000000000000000000000"+(t?"1":"0")},s=function(t){return i(new BigNumber(t).times(new BigNumber(2).pow(128)))},c=function(t){return"1"===new BigNumber(t.substr(0,1),16).toString(2).substr(0,1)},l=function(t){return t=t||"0",c(t)?new BigNumber(t,16).minus(new BigNumber("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",16)).minus(1):new BigNumber(t,16)},f=function(t){return t=t||"0",new BigNumber(t,16)},p=function(t){return l(t).dividedBy(new BigNumber(2).pow(128))},m=function(t){return f(t).dividedBy(new BigNumber(2).pow(128))},d=function(t){return"0x"+t},h=function(t){return"0000000000000000000000000000000000000000000000000000000000000001"===t?!0:!1},g=function(t){return n.toAscii(t)},y=function(t){return"0x"+t.slice(t.length-40,t.length)};e.exports={formatInputInt:i,formatInputString:a,formatInputBool:u,formatInputReal:s,formatOutputInt:l,formatOutputUInt:f,formatOutputReal:p,formatOutputUReal:m,formatOutputHash:d,formatOutputBool:h,formatOutputString:g,formatOutputAddress:y}},{"../utils/config":4,"../utils/utils":5}],3:[function(t,e){var n=t("./formatters"),r=function(t){return function(e){return 0===e.indexOf(t)}},o=function(t){return function(e){return t===e}},i=function(){return[{type:r("uint"),format:n.formatInputInt},{type:r("int"),format:n.formatInputInt},{type:r("bytes"),format:n.formatInputString},{type:r("real"),format:n.formatInputReal},{type:r("ureal"),format:n.formatInputReal},{type:o("address"),format:n.formatInputInt},{type:o("bool"),format:n.formatInputBool}]},a=function(){return[{type:r("uint"),format:n.formatOutputUInt},{type:r("int"),format:n.formatOutputInt},{type:r("bytes"),format:n.formatOutputString},{type:r("real"),format:n.formatOutputReal},{type:r("ureal"),format:n.formatOutputUReal},{type:o("address"),format:n.formatOutputAddress},{type:o("bool"),format:n.formatOutputBool}]};e.exports={prefixedType:r,namedType:o,inputTypes:i,outputTypes:a}},{"./formatters":2}],4:[function(t,e){var n=["wei","Kwei","Mwei","Gwei","szabo","finney","ether","grand","Mether","Gether","Tether","Pether","Eether","Zether","Yether","Nether","Dether","Vether","Uether"];e.exports={ETH_PADDING:32,ETH_SIGNATURE_LENGTH:4,ETH_UNITS:n,ETH_BIGNUMBER_ROUNDING_MODE:{ROUNDING_MODE:BigNumber.ROUND_DOWN},ETH_POLLING_TIMEOUT:1e3,ETH_DEFAULTBLOCK:"latest"}},{}],5:[function(t,e){var n={wei:"1",kwei:"1000",ada:"1000",mwei:"1000000",babbage:"1000000",gwei:"1000000000",shannon:"1000000000",szabo:"1000000000000",finney:"1000000000000000",ether:"1000000000000000000",kether:"1000000000000000000000",grand:"1000000000000000000000",einstein:"1000000000000000000000",mether:"1000000000000000000000000",gether:"1000000000000000000000000000",tether:"1000000000000000000000000000000"},r=function(t,e){for(var n=!1,r=0;rn;n+=2){var o=parseInt(t.substr(n,2),16);if(0===o)break;e+=String.fromCharCode(o)}return e},i=function(t){for(var e="",n=0;n1?(t[n[0]]||(t[n[0]]={}),t[n[0]][n[1]]=r):t[n[0]]=r})},g=function(t,e){e.forEach(function(e){var n=e.name.split("."),r={};r.get=function(){return e.newProperty&&console.warn("This property is deprecated please use web3."+e.newProperty+" instead."),x.manager.send({method:e.getter,outputFormatter:e.outputFormatter})},e.setter&&(r.set=function(t){return e.newProperty&&console.warn("This property is deprecated please use web3."+e.newProperty+" instead."),x.manager.send({method:e.setter,params:[t],inputFormatter:e.inputFormatter})}),r.enumerable=!e.newProperty,n.length>1?(t[n[0]]||(t[n[0]]={}),Object.defineProperty(t[n[0]],n[1],r)):Object.defineProperty(t,e.name,r)})},y=function(t,e,n,r){x.manager.startPolling({method:t,params:[e]},e,n,r)},b=function(t){x.manager.stopPolling(t)},v={startPolling:y.bind(null,"eth_getFilterChanges"),stopPolling:b},w={startPolling:y.bind(null,"shh_getFilterChanges"),stopPolling:b},x={version:{api:n.version},manager:f(),providers:{},setProvider:function(t){x.manager.setProvider(t)},reset:function(){x.manager.reset()},toHex:c.toHex,toAscii:c.toAscii,fromAscii:c.fromAscii,toDecimal:c.toDecimal,fromDecimal:c.fromDecimal,toBigNumber:c.toBigNumber,toWei:c.toWei,fromWei:c.fromWei,isAddress:c.isAddress,net:{},eth:{contractFromAbi:function(t){return console.warn("Initiating a contract like this is deprecated please use var MyContract = eth.contract(abi); new MyContract(address); instead."),function(e){e=e||"0xc6d9d2cd449a754c494264e1809c50e34d64562b";var n=x.eth.contract(e,t);return n.address=e,n}},filter:function(t,e,n){return t._isEvent?t(e,n):s(t,v,l.outputLogFormatter)},watch:function(t,e,n){return console.warn("eth.watch() is deprecated please use eth.filter() instead."),this.filter(t,e,n)}},db:{},shh:{filter:function(t){return s(t,w,l.outputPostFormatter)},watch:function(t){return console.warn("shh.watch() is deprecated please use shh.filter() instead."),this.filter(t)}}};Object.defineProperty(x.eth,"defaultBlock",{get:function(){return p.ETH_DEFAULTBLOCK},set:function(t){return p.ETH_DEFAULTBLOCK=t,p.ETH_DEFAULTBLOCK}}),h(x,m),g(x,d),h(x.net,r.methods),g(x.net,r.properties),h(x.eth,o.methods),g(x.eth,o.properties),h(x.db,i.methods()),h(x.shh,a.methods()),h(v,u.eth()),h(w,u.shh()),e.exports=x},{"../version.json":21,"./solidity/formatters":2,"./utils/config":4,"./utils/utils":5,"./web3/db":8,"./web3/eth":9,"./web3/filter":11,"./web3/net":15,"./web3/requestmanager":17,"./web3/shh":18,"./web3/watches":20}],7:[function(t,e){function n(t,e){t.forEach(function(t){if(-1===t.name.indexOf("(")){var e=t.name,n=t.inputs.map(function(t){return t.type}).join();t.name=e+"("+n+")"}});var n={};return c(n),l(n,t,e),f(n,t,e),p(n,t,e),n}var r=t("../web3"),o=t("../solidity/abi"),i=t("../utils/utils"),a=t("./event"),u=t("./signature"),s=function(t){r._currentContractAbi=t.abi,r._currentContractAddress=t.address,r._currentContractMethodName=t.method,r._currentContractMethodParams=t.params},c=function(t){t.call=function(e){return t._isTransaction=!1,t._options=e,t},t.sendTransaction=function(e){return t._isTransaction=!0,t._options=e,t},t.transact=function(e){return console.warn("myContract.transact() is deprecated please use myContract.sendTransaction() instead."),t.sendTransaction(e)},t._options={},["gas","gasPrice","value","from"].forEach(function(e){t[e]=function(n){return t._options[e]=n,t}})},l=function(t,e,n){var a=o.inputParser(e),c=o.outputParser(e);i.filterFunctions(e).forEach(function(o){var l=i.extractDisplayName(o.name),f=i.extractTypeName(o.name),p=function(){var i=Array.prototype.slice.call(arguments),p=u.functionSignatureFromAscii(o.name),m=a[l][f].apply(null,i),d=t._options||{};d.to=n,d.data=p+m;var h=t._isTransaction===!0||t._isTransaction!==!1&&!o.constant,g=d.collapse!==!1;if(t._options={},t._isTransaction=null,h)return s({abi:e,address:n,method:o.name,params:i}),void r.eth.sendTransaction(d);var y=r.eth.call(d),b=c[l][f](y);return g&&(1===b.length?b=b[0]:0===b.length&&(b=null)),b};void 0===t[l]&&(t[l]=p),t[l][f]=p})},f=function(t,e,n){t.address=n,t._onWatchEventResult=function(t){var n=event.getMatchingEvent(i.filterEvents(e)),r=a.outputParser(n);return r(t)},Object.defineProperty(t,"topics",{get:function(){return i.filterEvents(e).map(function(t){return u.eventSignatureFromAscii(t.name)})}})},p=function(t,e,n){i.filterEvents(e).forEach(function(e){var o=function(){var t=Array.prototype.slice.call(arguments),o=u.eventSignatureFromAscii(e.name),i=a.inputParser(n,o,e),s=i.apply(null,t),c=function(t){var n=a.outputParser(e);return n(t)};return r.eth.filter(s,void 0,void 0,c)};o._isEvent=!0;var s=i.extractDisplayName(e.name),c=i.extractTypeName(e.name);void 0===t[s]&&(t[s]=o),t[s][c]=o})},m=function(t){return t instanceof Array&&1===arguments.length?n.bind(null,t):(console.warn("Initiating a contract like this is deprecated please use var MyContract = eth.contract(abi); new MyContract(address); instead."),new n(arguments[1],arguments[0]))};e.exports=m},{"../solidity/abi":1,"../utils/utils":5,"../web3":6,"./event":10,"./signature":19}],8:[function(t,e){var n=function(){return[{name:"putString",call:"db_putString"},{name:"getString",call:"db_getString"},{name:"putHex",call:"db_putHex"},{name:"getHex",call:"db_getHex"}]};e.exports={methods:n}},{}],9:[function(t,e){var n=t("./formatters"),r=t("../utils/utils"),o=function(t){return r.isString(t[0])&&0===t[0].indexOf("0x")?"eth_getBlockByHash":"eth_getBlockByNumber"},i=function(t){return r.isString(t[0])&&0===t[0].indexOf("0x")?"eth_getTransactionByBlockHashAndIndex":"eth_getTransactionByBlockNumberAndIndex"},a=function(t){return r.isString(t[0])&&0===t[0].indexOf("0x")?"eth_getUncleByBlockHashAndIndex":"eth_getUncleByBlockNumberAndIndex"},u=function(t){return r.isString(t[0])&&0===t[0].indexOf("0x")?"eth_getBlockTransactionCountByHash":"eth_getBlockTransactionCountByNumber"},s=function(t){return r.isString(t[0])&&0===t[0].indexOf("0x")?"eth_getUncleCountByBlockHash":"eth_getUncleCountByBlockNumber"},c=[{name:"getBalance",call:"eth_getBalance",addDefaultblock:2,outputFormatter:n.convertToBigNumber},{name:"getStorage",call:"eth_getStorage",addDefaultblock:2},{name:"getStorageAt",call:"eth_getStorageAt",addDefaultblock:3,inputFormatter:r.toHex},{name:"getData",call:"eth_getData",addDefaultblock:2},{name:"getBlock",call:o,outputFormatter:n.outputBlockFormatter,inputFormatter:[r.toHex,function(t){return t?!0:!1}]},{name:"getUncle",call:a,outputFormatter:n.outputBlockFormatter,inputFormatter:[r.toHex,r.toHex,function(t){return t?!0:!1}]},{name:"getCompilers",call:"eth_getCompilers"},{name:"getBlockTransactionCount",call:u,outputFormatter:r.toDecimal,inputFormatter:r.toHex},{name:"getBlockUncleCount",call:s,outputFormatter:r.toDecimal,inputFormatter:r.toHex},{name:"getTransaction",call:"eth_getTransactionByHash",outputFormatter:n.outputTransactionFormatter},{name:"getTransactionFromBlock",call:i,outputFormatter:n.outputTransactionFormatter,inputFormatter:r.toHex},{name:"getTransactionCount",call:"eth_getTransactionCount",addDefaultblock:2,outputFormatter:r.toDecimal},{name:"sendTransaction",call:"eth_sendTransaction",inputFormatter:n.inputTransactionFormatter},{name:"call",call:"eth_call",addDefaultblock:2,inputFormatter:n.inputCallFormatter},{name:"compile.solidity",call:"eth_compileSolidity"},{name:"compile.lll",call:"eth_compileLLL",inputFormatter:r.toHex},{name:"compile.serpent",call:"eth_compileSerpent",inputFormatter:r.toHex},{name:"flush",call:"eth_flush"},{name:"balanceAt",call:"eth_balanceAt",newMethod:"eth.getBalance"},{name:"stateAt",call:"eth_stateAt",newMethod:"eth.getStorageAt"},{name:"storageAt",call:"eth_storageAt",newMethod:"eth.getStorage"},{name:"countAt",call:"eth_countAt",newMethod:"eth.getTransactionCount"},{name:"codeAt",call:"eth_codeAt",newMethod:"eth.getData"},{name:"transact",call:"eth_transact",newMethod:"eth.sendTransaction"},{name:"block",call:o,newMethod:"eth.getBlock"},{name:"transaction",call:i,newMethod:"eth.getTransaction"},{name:"uncle",call:a,newMethod:"eth.getUncle"},{name:"compilers",call:"eth_compilers",newMethod:"eth.getCompilers"},{name:"solidity",call:"eth_solidity",newMethod:"eth.compile.solidity"},{name:"lll",call:"eth_lll",newMethod:"eth.compile.lll"},{name:"serpent",call:"eth_serpent",newMethod:"eth.compile.serpent"},{name:"transactionCount",call:u,newMethod:"eth.getBlockTransactionCount"},{name:"uncleCount",call:s,newMethod:"eth.getBlockUncleCount"},{name:"logs",call:"eth_logs"}],l=[{name:"coinbase",getter:"eth_coinbase"},{name:"mining",getter:"eth_mining"},{name:"gasPrice",getter:"eth_gasPrice",outputFormatter:n.convertToBigNumber},{name:"accounts",getter:"eth_accounts"},{name:"blockNumber",getter:"eth_blockNumber",outputFormatter:r.toDecimal},{name:"listening",getter:"net_listening",setter:"eth_setListening",newProperty:"net.listening"},{name:"peerCount",getter:"net_peerCount",newProperty:"net.peerCount"},{name:"number",getter:"eth_number",newProperty:"eth.blockNumber"}];e.exports={methods:c,properties:l}},{"../utils/utils":5,"./formatters":12}],10:[function(t,e){var n=t("../solidity/abi"),r=t("../utils/utils"),o=t("./signature"),i=function(t,e){return t.filter(function(t){return t.indexed===e})},a=function(t,e){var n=r.findIndex(t,function(t){return t.name===e});return-1===n?void console.error("indexed param with name "+e+" not found"):t[n]},u=function(t,e){return Object.keys(e).map(function(r){var o=[a(i(t.inputs,!0),r)],u=e[r];return u instanceof Array?u.map(function(t){return n.formatInput(o,[t])}):n.formatInput(o,[u])})},s=function(t,e,n){return function(r,o){var i=o||{};return i.address=t,i.topics=[],i.topics.push(e),r&&(i.topics=i.topics.concat(u(n,r))),i}},c=function(t,e,n){var r=e.slice(),o=n.slice();return t.reduce(function(t,e){var n;return n=e.indexed?r.splice(0,1)[0]:o.splice(0,1)[0],t[e.name]=n,t},{})},l=function(t){return function(e){var o={event:r.extractDisplayName(t.name),number:e.number,hash:e.hash,args:{}};if(e.topics=e.topic,!e.topics)return o;var a=i(t.inputs,!0),u="0x"+e.topics.slice(1,e.topics.length).map(function(t){return t.slice(2)}).join(""),s=n.formatOutput(a,u),l=i(t.inputs,!1),f=n.formatOutput(l,e.data);return o.args=c(t.inputs,s,f),o}},f=function(t,e){for(var n=0;ny;y++)g.push(d(e.slice(0,s))),e=e.slice(s);n.push(g)}else o.prefixedType("bytes")(t[c].type)?(l=l.slice(s),n.push(d(e.slice(0,s))),e=e.slice(s)):(n.push(d(e.slice(0,s))),e=e.slice(s))}),n},d=function(t){var e={};return t.forEach(function(t){var r=n.extractDisplayName(t.name),o=n.extractTypeName(t.name),i=function(){var e=Array.prototype.slice.call(arguments);return l(t.inputs,e)};void 0===e[r]&&(e[r]=i),e[r][o]=i}),e},h=function(t){var e={};return t.forEach(function(t){var r=n.extractDisplayName(t.name),o=n.extractTypeName(t.name),i=function(e){return m(t.outputs,e)};void 0===e[r]&&(e[r]=i),e[r][o]=i}),e};e.exports={inputParser:d,outputParser:h,formatInput:l,formatOutput:m}},{"../utils/config":4,"../utils/utils":5,"./formatters":2,"./types":3}],2:[function(t,e){var n=t("../utils/utils"),r=t("../utils/config"),o=function(t,e,n){return new Array(e-t.length+1).join(n?n:"0")+t},i=function(t){var e=2*r.ETH_PADDING;return BigNumber.config(r.ETH_BIGNUMBER_ROUNDING_MODE),o(n.toTwosComplement(t).round().toString(16),e)},a=function(t){return n.fromAscii(t,r.ETH_PADDING).substr(2)},u=function(t){return"000000000000000000000000000000000000000000000000000000000000000"+(t?"1":"0")},s=function(t){return i(new BigNumber(t).times(new BigNumber(2).pow(128)))},c=function(t){return"1"===new BigNumber(t.substr(0,1),16).toString(2).substr(0,1)},l=function(t){return t=t||"0",c(t)?new BigNumber(t,16).minus(new BigNumber("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",16)).minus(1):new BigNumber(t,16)},f=function(t){return t=t||"0",new BigNumber(t,16)},p=function(t){return l(t).dividedBy(new BigNumber(2).pow(128))},m=function(t){return f(t).dividedBy(new BigNumber(2).pow(128))},d=function(t){return"0x"+t},h=function(t){return"0000000000000000000000000000000000000000000000000000000000000001"===t?!0:!1},g=function(t){return n.toAscii(t)},y=function(t){return"0x"+t.slice(t.length-40,t.length)};e.exports={formatInputInt:i,formatInputString:a,formatInputBool:u,formatInputReal:s,formatOutputInt:l,formatOutputUInt:f,formatOutputReal:p,formatOutputUReal:m,formatOutputHash:d,formatOutputBool:h,formatOutputString:g,formatOutputAddress:y}},{"../utils/config":4,"../utils/utils":5}],3:[function(t,e){var n=t("./formatters"),r=function(t){return function(e){return 0===e.indexOf(t)}},o=function(t){return function(e){return t===e}},i=function(){return[{type:r("uint"),format:n.formatInputInt},{type:r("int"),format:n.formatInputInt},{type:r("bytes"),format:n.formatInputString},{type:r("real"),format:n.formatInputReal},{type:r("ureal"),format:n.formatInputReal},{type:o("address"),format:n.formatInputInt},{type:o("bool"),format:n.formatInputBool}]},a=function(){return[{type:r("uint"),format:n.formatOutputUInt},{type:r("int"),format:n.formatOutputInt},{type:r("bytes"),format:n.formatOutputString},{type:r("real"),format:n.formatOutputReal},{type:r("ureal"),format:n.formatOutputUReal},{type:o("address"),format:n.formatOutputAddress},{type:o("bool"),format:n.formatOutputBool}]};e.exports={prefixedType:r,namedType:o,inputTypes:i,outputTypes:a}},{"./formatters":2}],4:[function(t,e){var n=["wei","Kwei","Mwei","Gwei","szabo","finney","ether","grand","Mether","Gether","Tether","Pether","Eether","Zether","Yether","Nether","Dether","Vether","Uether"];e.exports={ETH_PADDING:32,ETH_SIGNATURE_LENGTH:4,ETH_UNITS:n,ETH_BIGNUMBER_ROUNDING_MODE:{ROUNDING_MODE:BigNumber.ROUND_DOWN},ETH_POLLING_TIMEOUT:1e3,ETH_DEFAULTBLOCK:"latest"}},{}],5:[function(t,e){var n={wei:"1",kwei:"1000",ada:"1000",mwei:"1000000",babbage:"1000000",gwei:"1000000000",shannon:"1000000000",szabo:"1000000000000",finney:"1000000000000000",ether:"1000000000000000000",kether:"1000000000000000000000",grand:"1000000000000000000000",einstein:"1000000000000000000000",mether:"1000000000000000000000000",gether:"1000000000000000000000000000",tether:"1000000000000000000000000000000"},r=function(t,e){for(var n=!1,r=0;rn;n+=2){var o=parseInt(t.substr(n,2),16);if(0===o)break;e+=String.fromCharCode(o)}return e},i=function(t){for(var e="",n=0;n1?(t[n[0]]||(t[n[0]]={}),t[n[0]][n[1]]=r):t[n[0]]=r})},g=function(t,e){e.forEach(function(e){var n=e.name.split("."),r={};r.get=function(){return e.newProperty&&console.warn("This property is deprecated please use web3."+e.newProperty+" instead."),_.manager.send({method:e.getter,outputFormatter:e.outputFormatter})},e.setter&&(r.set=function(t){return e.newProperty&&console.warn("This property is deprecated please use web3."+e.newProperty+" instead."),_.manager.send({method:e.setter,params:[t],inputFormatter:e.inputFormatter})}),r.enumerable=!e.newProperty,n.length>1?(t[n[0]]||(t[n[0]]={}),Object.defineProperty(t[n[0]],n[1],r)):Object.defineProperty(t,e.name,r)})},y=function(t,e,n,r){_.manager.startPolling({method:t,params:[e]},e,n,r)},b=function(t){_.manager.stopPolling(t)},v={startPolling:y.bind(null,"eth_getFilterChanges"),stopPolling:b},w={startPolling:y.bind(null,"shh_getFilterChanges"),stopPolling:b},_={version:{api:n.version},manager:f(),providers:{},setProvider:function(t){_.manager.setProvider(t)},reset:function(){_.manager.reset()},toHex:c.toHex,toAscii:c.toAscii,fromAscii:c.fromAscii,toDecimal:c.toDecimal,fromDecimal:c.fromDecimal,toBigNumber:c.toBigNumber,toWei:c.toWei,fromWei:c.fromWei,isAddress:c.isAddress,net:{},eth:{contractFromAbi:function(t){return console.warn("Initiating a contract like this is deprecated please use var MyContract = eth.contract(abi); new MyContract(address); instead."),function(e){e=e||"0xc6d9d2cd449a754c494264e1809c50e34d64562b";var n=_.eth.contract(e,t);return n.address=e,n}},filter:function(t,e,n){return t._isEvent?t(e,n):s(t,v,l.outputLogFormatter)},watch:function(t,e,n){return console.warn("eth.watch() is deprecated please use eth.filter() instead."),this.filter(t,e,n)}},db:{},shh:{filter:function(t){return s(t,w,l.outputPostFormatter)},watch:function(t){return console.warn("shh.watch() is deprecated please use shh.filter() instead."),this.filter(t)}}};Object.defineProperty(_.eth,"defaultBlock",{get:function(){return p.ETH_DEFAULTBLOCK},set:function(t){return p.ETH_DEFAULTBLOCK=t,p.ETH_DEFAULTBLOCK}}),h(_,m),g(_,d),h(_.net,r.methods),g(_.net,r.properties),h(_.eth,o.methods),g(_.eth,o.properties),h(_.db,i.methods()),h(_.shh,a.methods()),h(v,u.eth()),h(w,u.shh()),e.exports=_},{"../version.json":21,"./solidity/formatters":2,"./utils/config":4,"./utils/utils":5,"./web3/db":8,"./web3/eth":9,"./web3/filter":11,"./web3/net":15,"./web3/requestmanager":17,"./web3/shh":18,"./web3/watches":20}],7:[function(t,e){function n(t,e){t.forEach(function(t){if(-1===t.name.indexOf("(")){var e=t.name,n=t.inputs.map(function(t){return t.type}).join();t.name=e+"("+n+")"}});var n={};return c(n),l(n,t,e),f(n,t,e),p(n,t,e),n}var r=t("../web3"),o=t("../solidity/abi"),i=t("../utils/utils"),a=t("./event"),u=t("./signature"),s=function(t){r._currentContractAbi=t.abi,r._currentContractAddress=t.address,r._currentContractMethodName=t.method,r._currentContractMethodParams=t.params},c=function(t){t.call=function(e){return t._isTransaction=!1,t._options=e,t},t.sendTransaction=function(e){return t._isTransaction=!0,t._options=e,t},t.transact=function(e){return console.warn("myContract.transact() is deprecated please use myContract.sendTransaction() instead."),t.sendTransaction(e)},t._options={},["gas","gasPrice","value","from"].forEach(function(e){t[e]=function(n){return t._options[e]=n,t}})},l=function(t,e,n){var a=o.inputParser(e),c=o.outputParser(e);i.filterFunctions(e).forEach(function(o){var l=i.extractDisplayName(o.name),f=i.extractTypeName(o.name),p=function(){var i=Array.prototype.slice.call(arguments),p=u.functionSignatureFromAscii(o.name),m=a[l][f].apply(null,i),d=t._options||{};d.to=n,d.data=p+m;var h=t._isTransaction===!0||t._isTransaction!==!1&&!o.constant,g=d.collapse!==!1;if(t._options={},t._isTransaction=null,h)return s({abi:e,address:n,method:o.name,params:i}),void r.eth.sendTransaction(d);var y=r.eth.call(d),b=c[l][f](y);return g&&(1===b.length?b=b[0]:0===b.length&&(b=null)),b};void 0===t[l]&&(t[l]=p),t[l][f]=p})},f=function(t,e,n){t.address=n,t._onWatchEventResult=function(t){var n=event.getMatchingEvent(i.filterEvents(e)),r=a.outputParser(n);return r(t)},Object.defineProperty(t,"topics",{get:function(){return i.filterEvents(e).map(function(t){return u.eventSignatureFromAscii(t.name)})}})},p=function(t,e,n){i.filterEvents(e).forEach(function(e){var o=function(){var t=Array.prototype.slice.call(arguments),o=u.eventSignatureFromAscii(e.name),i=a.inputParser(n,o,e),s=i.apply(null,t),c=function(t){var n=a.outputParser(e);return n(t)};return r.eth.filter(s,void 0,void 0,c)};o._isEvent=!0;var s=i.extractDisplayName(e.name),c=i.extractTypeName(e.name);void 0===t[s]&&(t[s]=o),t[s][c]=o})},m=function(t){return t instanceof Array&&1===arguments.length?n.bind(null,t):(console.warn("Initiating a contract like this is deprecated please use var MyContract = eth.contract(abi); new MyContract(address); instead."),new n(arguments[1],arguments[0]))};e.exports=m},{"../solidity/abi":1,"../utils/utils":5,"../web3":6,"./event":10,"./signature":19}],8:[function(t,e){var n=function(){return[{name:"putString",call:"db_putString"},{name:"getString",call:"db_getString"},{name:"putHex",call:"db_putHex"},{name:"getHex",call:"db_getHex"}]};e.exports={methods:n}},{}],9:[function(t,e){var n=t("./formatters"),r=t("../utils/utils"),o=function(t){return r.isString(t[0])&&0===t[0].indexOf("0x")?"eth_getBlockByHash":"eth_getBlockByNumber"},i=function(t){return r.isString(t[0])&&0===t[0].indexOf("0x")?"eth_getTransactionByBlockHashAndIndex":"eth_getTransactionByBlockNumberAndIndex"},a=function(t){return r.isString(t[0])&&0===t[0].indexOf("0x")?"eth_getUncleByBlockHashAndIndex":"eth_getUncleByBlockNumberAndIndex"},u=function(t){return r.isString(t[0])&&0===t[0].indexOf("0x")?"eth_getBlockTransactionCountByHash":"eth_getBlockTransactionCountByNumber"},s=function(t){return r.isString(t[0])&&0===t[0].indexOf("0x")?"eth_getUncleCountByBlockHash":"eth_getUncleCountByBlockNumber"},c=[{name:"getBalance",call:"eth_getBalance",addDefaultblock:2,outputFormatter:n.convertToBigNumber},{name:"getStorageAt",call:"eth_getStorageAt",addDefaultblock:3,inputFormatter:r.toHex},{name:"getCode",call:"eth_getCode",addDefaultblock:2},{name:"getBlock",call:o,outputFormatter:n.outputBlockFormatter,inputFormatter:[r.toHex,function(t){return t?!0:!1}]},{name:"getUncle",call:a,outputFormatter:n.outputBlockFormatter,inputFormatter:[r.toHex,r.toHex,function(t){return t?!0:!1}]},{name:"getCompilers",call:"eth_getCompilers"},{name:"getBlockTransactionCount",call:u,outputFormatter:r.toDecimal,inputFormatter:r.toHex},{name:"getBlockUncleCount",call:s,outputFormatter:r.toDecimal,inputFormatter:r.toHex},{name:"getTransaction",call:"eth_getTransactionByHash",outputFormatter:n.outputTransactionFormatter},{name:"getTransactionFromBlock",call:i,outputFormatter:n.outputTransactionFormatter,inputFormatter:r.toHex},{name:"getTransactionCount",call:"eth_getTransactionCount",addDefaultblock:2,outputFormatter:r.toDecimal},{name:"sendTransaction",call:"eth_sendTransaction",inputFormatter:n.inputTransactionFormatter},{name:"call",call:"eth_call",addDefaultblock:2,inputFormatter:n.inputCallFormatter},{name:"compile.solidity",call:"eth_compileSolidity"},{name:"compile.lll",call:"eth_compileLLL",inputFormatter:r.toHex},{name:"compile.serpent",call:"eth_compileSerpent",inputFormatter:r.toHex},{name:"flush",call:"eth_flush"},{name:"balanceAt",call:"eth_balanceAt",newMethod:"eth.getBalance"},{name:"stateAt",call:"eth_stateAt",newMethod:"eth.getStorageAt"},{name:"storageAt",call:"eth_storageAt",newMethod:"eth.getStorage"},{name:"countAt",call:"eth_countAt",newMethod:"eth.getTransactionCount"},{name:"codeAt",call:"eth_codeAt",newMethod:"eth.getCode"},{name:"transact",call:"eth_transact",newMethod:"eth.sendTransaction"},{name:"block",call:o,newMethod:"eth.getBlock"},{name:"transaction",call:i,newMethod:"eth.getTransaction"},{name:"uncle",call:a,newMethod:"eth.getUncle"},{name:"compilers",call:"eth_compilers",newMethod:"eth.getCompilers"},{name:"solidity",call:"eth_solidity",newMethod:"eth.compile.solidity"},{name:"lll",call:"eth_lll",newMethod:"eth.compile.lll"},{name:"serpent",call:"eth_serpent",newMethod:"eth.compile.serpent"},{name:"transactionCount",call:u,newMethod:"eth.getBlockTransactionCount"},{name:"uncleCount",call:s,newMethod:"eth.getBlockUncleCount"},{name:"logs",call:"eth_logs"}],l=[{name:"coinbase",getter:"eth_coinbase"},{name:"mining",getter:"eth_mining"},{name:"gasPrice",getter:"eth_gasPrice",outputFormatter:n.convertToBigNumber},{name:"accounts",getter:"eth_accounts"},{name:"blockNumber",getter:"eth_blockNumber",outputFormatter:r.toDecimal},{name:"listening",getter:"net_listening",setter:"eth_setListening",newProperty:"net.listening"},{name:"peerCount",getter:"net_peerCount",newProperty:"net.peerCount"},{name:"number",getter:"eth_number",newProperty:"eth.blockNumber"}];e.exports={methods:c,properties:l}},{"../utils/utils":5,"./formatters":12}],10:[function(t,e){var n=t("../solidity/abi"),r=t("../utils/utils"),o=t("./signature"),i=function(t,e){return t.filter(function(t){return t.indexed===e})},a=function(t,e){var n=r.findIndex(t,function(t){return t.name===e});return-1===n?void console.error("indexed param with name "+e+" not found"):t[n]},u=function(t,e){return Object.keys(e).map(function(r){var o=[a(i(t.inputs,!0),r)],u=e[r];return u instanceof Array?u.map(function(t){return n.formatInput(o,[t])}):n.formatInput(o,[u])})},s=function(t,e,n){return function(r,o){var i=o||{};return i.address=t,i.topics=[],i.topics.push(e),r&&(i.topics=i.topics.concat(u(n,r))),i}},c=function(t,e,n){var r=e.slice(),o=n.slice();return t.reduce(function(t,e){var n;return n=e.indexed?r.splice(0,1)[0]:o.splice(0,1)[0],t[e.name]=n,t},{})},l=function(t){return function(e){var o={event:r.extractDisplayName(t.name),number:e.number,hash:e.hash,args:{}};if(e.topics=e.topic,!e.topics)return o;var a=i(t.inputs,!0),u="0x"+e.topics.slice(1,e.topics.length).map(function(t){return t.slice(2)}).join(""),s=n.formatOutput(a,u),l=i(t.inputs,!1),f=n.formatOutput(l,e.data);return o.args=c(t.inputs,s,f),o}},f=function(t,e){for(var n=0;n Date: Sat, 21 Mar 2015 20:42:02 +0100 Subject: [PATCH 21/66] Don't accept default argument for eth. Fixes #1250. Remove pointless exception. Reduce JS verbosity. --- eth/main.cpp | 7 +++++-- libethcore/Exceptions.h | 1 - libjsqrc/ethereumjs/dist/ethereum.js | 1 - libjsqrc/ethereumjs/dist/ethereum.js.map | 4 ++-- libjsqrc/ethereumjs/dist/ethereum.min.js | 2 +- 5 files changed, 8 insertions(+), 7 deletions(-) diff --git a/eth/main.cpp b/eth/main.cpp index f951f5a3c..ce89e8ddf 100644 --- a/eth/main.cpp +++ b/eth/main.cpp @@ -103,7 +103,7 @@ void interactiveHelp() void help() { cout - << "Usage eth [OPTIONS] " << endl + << "Usage eth [OPTIONS]" << endl << "Options:" << endl << " -a,--address Set the coinbase (mining payout) address to addr (default: auto)." << endl << " -b,--bootstrap Connect to the default Ethereum peerserver." << endl @@ -407,7 +407,10 @@ int main(int argc, char** argv) else if (arg == "-V" || arg == "--version") version(); else - remoteHost = argv[i]; + { + cerr << "Invalid argument: " << arg << endl; + exit(-1); + } } if (!clientName.empty()) diff --git a/libethcore/Exceptions.h b/libethcore/Exceptions.h index f9eab7c8d..df6a08817 100644 --- a/libethcore/Exceptions.h +++ b/libethcore/Exceptions.h @@ -59,7 +59,6 @@ struct InvalidGasUsed: virtual dev::Exception {}; class InvalidTransactionsHash: virtual public dev::Exception {}; struct InvalidTransaction: virtual dev::Exception {}; struct InvalidDifficulty: virtual dev::Exception {}; -struct InvalidSeedHash: virtual dev::Exception {}; class InvalidGasLimit: virtual public dev::Exception {}; struct InvalidTransactionGasUsed: virtual dev::Exception {}; struct InvalidTransactionsStateRoot: virtual dev::Exception {}; diff --git a/libjsqrc/ethereumjs/dist/ethereum.js b/libjsqrc/ethereumjs/dist/ethereum.js index d8f1a7cef..8d00981c0 100644 --- a/libjsqrc/ethereumjs/dist/ethereum.js +++ b/libjsqrc/ethereumjs/dist/ethereum.js @@ -2048,7 +2048,6 @@ var filter = function(options, implementation, formatter) { // call the callbacks var onMessages = function (messages) { messages.forEach(function (message) { - console.log("Got message: " + JSON.stringify(message)); message = formatter ? formatter(message) : message; callbacks.forEach(function (callback) { callback(message); diff --git a/libjsqrc/ethereumjs/dist/ethereum.js.map b/libjsqrc/ethereumjs/dist/ethereum.js.map index 0c38ccdbc..44144743f 100644 --- a/libjsqrc/ethereumjs/dist/ethereum.js.map +++ b/libjsqrc/ethereumjs/dist/ethereum.js.map @@ -26,7 +26,7 @@ "index.js" ], "names": [], - "mappings": "AAAA;ACAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACrPA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACtNA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC7EA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACvEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AChcA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC5SA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACnPA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACpCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACpJA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1IA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC5KA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC3MA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACrEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACjEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACzCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACjCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACjKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACjDA;AACA;AACA;;ACFA;AACA;AACA;AACA;AACA;AACA;AACA;AACA", + "mappings": "AAAA;ACAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACrPA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACtNA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC7EA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACvEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AChcA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC5SA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACnPA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACpCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACpJA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1IA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC3KA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC3MA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACrEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACjEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACzCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACjCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACjKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACjDA;AACA;AACA;;ACFA;AACA;AACA;AACA;AACA;AACA;AACA;AACA", "file": "generated.js", "sourceRoot": "", "sourcesContent": [ @@ -41,7 +41,7 @@ "/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/** @file db.js\n * @authors:\n * Marek Kotewicz \n * @date 2015\n */\n\n\n/// @returns an array of objects describing web3.db api methods\nvar methods = function () {\n return [\n { name: 'putString', call: 'db_putString'},\n { name: 'getString', call: 'db_getString'},\n { name: 'putHex', call: 'db_putHex'},\n { name: 'getHex', call: 'db_getHex'}\n ];\n};\n\nmodule.exports = {\n methods: methods\n};\n", "/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/** @file eth.js\n * @authors:\n * Marek Kotewicz \n * Fabian Vogelsteller \n * @date 2015\n */\n\n/**\n * Web3\n * \n * @module web3\n */\n\n/**\n * Eth methods and properties\n *\n * An example method object can look as follows:\n *\n * {\n * name: 'getBlock',\n * call: blockCall,\n * outputFormatter: formatters.outputBlockFormatter,\n * inputFormatter: [ // can be a formatter funciton or an array of functions. Where each item in the array will be used for one parameter\n * utils.toHex, // formats paramter 1\n * function(param){ if(!param) return false; } // formats paramter 2\n * ]\n * },\n *\n * @class [web3] eth\n * @constructor\n */\n\n\nvar formatters = require('./formatters');\nvar utils = require('../utils/utils');\n\n\nvar blockCall = function (args) {\n return (utils.isString(args[0]) && args[0].indexOf('0x') === 0) ? \"eth_getBlockByHash\" : \"eth_getBlockByNumber\";\n};\n\nvar transactionFromBlockCall = function (args) {\n return (utils.isString(args[0]) && args[0].indexOf('0x') === 0) ? 'eth_getTransactionByBlockHashAndIndex' : 'eth_getTransactionByBlockNumberAndIndex';\n};\n\nvar uncleCall = function (args) {\n return (utils.isString(args[0]) && args[0].indexOf('0x') === 0) ? 'eth_getUncleByBlockHashAndIndex' : 'eth_getUncleByBlockNumberAndIndex';\n};\n\nvar getBlockTransactionCountCall = function (args) {\n return (utils.isString(args[0]) && args[0].indexOf('0x') === 0) ? 'eth_getBlockTransactionCountByHash' : 'eth_getBlockTransactionCountByNumber';\n};\n\nvar uncleCountCall = function (args) {\n return (utils.isString(args[0]) && args[0].indexOf('0x') === 0) ? 'eth_getUncleCountByBlockHash' : 'eth_getUncleCountByBlockNumber';\n};\n\n/// @returns an array of objects describing web3.eth api methods\nvar methods = [\n { name: 'getBalance', call: 'eth_getBalance', addDefaultblock: 2,\n outputFormatter: formatters.convertToBigNumber},\n { name: 'getStorageAt', call: 'eth_getStorageAt', addDefaultblock: 3,\n inputFormatter: utils.toHex},\n\t{ name: 'getCode', call: 'eth_getCode', addDefaultblock: 2},\n { name: 'getBlock', call: blockCall,\n outputFormatter: formatters.outputBlockFormatter,\n inputFormatter: [utils.toHex, function(param){ return (!param) ? false : true; }]},\n { name: 'getUncle', call: uncleCall,\n outputFormatter: formatters.outputBlockFormatter,\n inputFormatter: [utils.toHex, utils.toHex, function(param){ return (!param) ? false : true; }]},\n { name: 'getCompilers', call: 'eth_getCompilers' },\n { name: 'getBlockTransactionCount', call: getBlockTransactionCountCall,\n outputFormatter: utils.toDecimal,\n inputFormatter: utils.toHex },\n { name: 'getBlockUncleCount', call: uncleCountCall,\n outputFormatter: utils.toDecimal,\n inputFormatter: utils.toHex },\n { name: 'getTransaction', call: 'eth_getTransactionByHash',\n outputFormatter: formatters.outputTransactionFormatter },\n { name: 'getTransactionFromBlock', call: transactionFromBlockCall,\n outputFormatter: formatters.outputTransactionFormatter,\n inputFormatter: utils.toHex },\n { name: 'getTransactionCount', call: 'eth_getTransactionCount', addDefaultblock: 2,\n outputFormatter: utils.toDecimal},\n { name: 'sendTransaction', call: 'eth_sendTransaction',\n inputFormatter: formatters.inputTransactionFormatter },\n { name: 'call', call: 'eth_call', addDefaultblock: 2,\n inputFormatter: formatters.inputCallFormatter },\n { name: 'compile.solidity', call: 'eth_compileSolidity' },\n { name: 'compile.lll', call: 'eth_compileLLL', inputFormatter: utils.toHex },\n { name: 'compile.serpent', call: 'eth_compileSerpent', inputFormatter: utils.toHex },\n { name: 'flush', call: 'eth_flush' },\n\n // deprecated methods\n { name: 'balanceAt', call: 'eth_balanceAt', newMethod: 'eth.getBalance' },\n { name: 'stateAt', call: 'eth_stateAt', newMethod: 'eth.getStorageAt' },\n { name: 'storageAt', call: 'eth_storageAt', newMethod: 'eth.getStorage' },\n { name: 'countAt', call: 'eth_countAt', newMethod: 'eth.getTransactionCount' },\n\t{ name: 'codeAt', call: 'eth_codeAt', newMethod: 'eth.getCode' },\n { name: 'transact', call: 'eth_transact', newMethod: 'eth.sendTransaction' },\n { name: 'block', call: blockCall, newMethod: 'eth.getBlock' },\n { name: 'transaction', call: transactionFromBlockCall, newMethod: 'eth.getTransaction' },\n { name: 'uncle', call: uncleCall, newMethod: 'eth.getUncle' },\n { name: 'compilers', call: 'eth_compilers', newMethod: 'eth.getCompilers' },\n { name: 'solidity', call: 'eth_solidity', newMethod: 'eth.compile.solidity' },\n { name: 'lll', call: 'eth_lll', newMethod: 'eth.compile.lll' },\n { name: 'serpent', call: 'eth_serpent', newMethod: 'eth.compile.serpent' },\n { name: 'transactionCount', call: getBlockTransactionCountCall, newMethod: 'eth.getBlockTransactionCount' },\n { name: 'uncleCount', call: uncleCountCall, newMethod: 'eth.getBlockUncleCount' },\n { name: 'logs', call: 'eth_logs' }\n];\n\n/// @returns an array of objects describing web3.eth api properties\nvar properties = [\n { name: 'coinbase', getter: 'eth_coinbase'},\n { name: 'mining', getter: 'eth_mining'},\n { name: 'gasPrice', getter: 'eth_gasPrice', outputFormatter: formatters.convertToBigNumber},\n { name: 'accounts', getter: 'eth_accounts' },\n { name: 'blockNumber', getter: 'eth_blockNumber', outputFormatter: utils.toDecimal},\n\n // deprecated properties\n { name: 'listening', getter: 'net_listening', setter: 'eth_setListening', newProperty: 'net.listening'},\n { name: 'peerCount', getter: 'net_peerCount', newProperty: 'net.peerCount'},\n { name: 'number', getter: 'eth_number', newProperty: 'eth.blockNumber'}\n];\n\n\nmodule.exports = {\n methods: methods,\n properties: properties\n};\n\n", "/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/** @file event.js\n * @authors:\n * Marek Kotewicz \n * @date 2014\n */\n\nvar abi = require('../solidity/abi');\nvar utils = require('../utils/utils');\nvar signature = require('./signature');\n\n/// filter inputs array && returns only indexed (or not) inputs\n/// @param inputs array\n/// @param bool if result should be an array of indexed params on not\n/// @returns array of (not?) indexed params\nvar filterInputs = function (inputs, indexed) {\n return inputs.filter(function (current) {\n return current.indexed === indexed;\n });\n};\n\nvar inputWithName = function (inputs, name) {\n var index = utils.findIndex(inputs, function (input) {\n return input.name === name;\n });\n \n if (index === -1) {\n console.error('indexed param with name ' + name + ' not found');\n return undefined;\n }\n return inputs[index];\n};\n\nvar indexedParamsToTopics = function (event, indexed) {\n // sort keys?\n return Object.keys(indexed).map(function (key) {\n var inputs = [inputWithName(filterInputs(event.inputs, true), key)];\n\n var value = indexed[key];\n if (value instanceof Array) {\n return value.map(function (v) {\n return abi.formatInput(inputs, [v]);\n }); \n }\n return abi.formatInput(inputs, [value]);\n });\n};\n\nvar inputParser = function (address, sign, event) {\n \n // valid options are 'earliest', 'latest', 'offset' and 'max', as defined for 'eth.filter'\n return function (indexed, options) {\n var o = options || {};\n o.address = address;\n o.topics = [];\n o.topics.push(sign);\n if (indexed) {\n o.topics = o.topics.concat(indexedParamsToTopics(event, indexed));\n }\n return o;\n };\n};\n\nvar getArgumentsObject = function (inputs, indexed, notIndexed) {\n var indexedCopy = indexed.slice();\n var notIndexedCopy = notIndexed.slice();\n return inputs.reduce(function (acc, current) {\n var value;\n if (current.indexed)\n value = indexedCopy.splice(0, 1)[0];\n else\n value = notIndexedCopy.splice(0, 1)[0];\n\n acc[current.name] = value;\n return acc;\n }, {}); \n};\n \nvar outputParser = function (event) {\n \n return function (output) {\n var result = {\n event: utils.extractDisplayName(event.name),\n number: output.number,\n hash: output.hash,\n args: {}\n };\n\n output.topics = output.topic; // fallback for go-ethereum\n if (!output.topics) {\n return result;\n }\n \n var indexedOutputs = filterInputs(event.inputs, true);\n var indexedData = \"0x\" + output.topics.slice(1, output.topics.length).map(function (topics) { return topics.slice(2); }).join(\"\");\n var indexedRes = abi.formatOutput(indexedOutputs, indexedData);\n\n var notIndexedOutputs = filterInputs(event.inputs, false);\n var notIndexedRes = abi.formatOutput(notIndexedOutputs, output.data);\n\n result.args = getArgumentsObject(event.inputs, indexedRes, notIndexedRes);\n\n return result;\n };\n};\n\nvar getMatchingEvent = function (events, payload) {\n for (var i = 0; i < events.length; i++) {\n var sign = signature.eventSignatureFromAscii(events[i].name); \n if (sign === payload.topics[0]) {\n return events[i];\n }\n }\n return undefined;\n};\n\n\nmodule.exports = {\n inputParser: inputParser,\n outputParser: outputParser,\n getMatchingEvent: getMatchingEvent\n};\n\n", - "/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/** @file filter.js\n * @authors:\n * Jeffrey Wilcke \n * Marek Kotewicz \n * Marian Oancea \n * Fabian Vogelsteller \n * Gav Wood \n * @date 2014\n */\n\nvar utils = require('../utils/utils');\n\n/// Should be called to check if filter implementation is valid\n/// @returns true if it is, otherwise false\nvar implementationIsValid = function (i) {\n return !!i && \n typeof i.newFilter === 'function' && \n typeof i.getLogs === 'function' && \n typeof i.uninstallFilter === 'function' &&\n typeof i.startPolling === 'function' &&\n typeof i.stopPolling === 'function';\n};\n\n/// This method should be called on options object, to verify deprecated properties && lazy load dynamic ones\n/// @param should be string or object\n/// @returns options string or object\nvar getOptions = function (options) {\n /*jshint maxcomplexity:9 */\n\n if (typeof options === 'string') {\n return options;\n } \n\n options = options || {};\n\n if (options.topic) {\n console.warn('\"topic\" is deprecated, is \"topics\" instead');\n options.topics = options.topic;\n }\n\n if (options.earliest) {\n console.warn('\"earliest\" is deprecated, is \"fromBlock\" instead');\n options.fromBlock = options.earliest;\n }\n\n if (options.latest) {\n console.warn('\"latest\" is deprecated, is \"toBlock\" instead');\n options.toBlock = options.latest;\n }\n\n // make sure topics, get converted to hex\n if(options.topics instanceof Array) {\n options.topics = options.topics.map(function(topic){\n return utils.toHex(topic);\n });\n }\n\n\tvar asBlockNumber = function(n) {\n\t\tif (n == null)\n\t\t\treturn null;\n\t\tif (n == 'latest' || n == 'pending')\n\t\t\treturn n;\n\t\treturn utils.toHex(n);\n\t};\n\n // evaluate lazy properties\n return {\n\t\tfromBlock: asBlockNumber(options.fromBlock),\n\t\ttoBlock: asBlockNumber(options.toBlock),\n to: options.to,\n address: options.address,\n topics: options.topics\n };\n};\n\n/// Should be used when we want to watch something\n/// it's using inner polling mechanism and is notified about changes\n/// @param options are filter options\n/// @param implementation, an abstract polling implementation\n/// @param formatter (optional), callback function which formats output before 'real' callback \nvar filter = function(options, implementation, formatter) {\n if (!implementationIsValid(implementation)) {\n console.error('filter implemenation is invalid');\n return;\n }\n\n options = getOptions(options);\n var callbacks = [];\n var filterId = implementation.newFilter(options);\n\n // call the callbacks\n var onMessages = function (messages) {\n messages.forEach(function (message) {\n\t\t\tconsole.log(\"Got message: \" + JSON.stringify(message));\n\t\t\tmessage = formatter ? formatter(message) : message;\n callbacks.forEach(function (callback) {\n\t\t\t\tcallback(message);\n });\n });\n };\n\n implementation.startPolling(filterId, onMessages, implementation.uninstallFilter);\n\n var watch = function(callback) {\n callbacks.push(callback);\n };\n\n var stopWatching = function() {\n implementation.stopPolling(filterId);\n implementation.uninstallFilter(filterId);\n callbacks = [];\n };\n\n var get = function () {\n var results = implementation.getLogs(filterId);\n\n return utils.isArray(results) ? results.map(function(message){\n return formatter ? formatter(message) : message;\n }) : results;\n };\n \n return {\n watch: watch,\n stopWatching: stopWatching,\n get: get,\n\n // DEPRECATED methods\n changed: function(){\n console.warn('watch().changed() is deprecated please use filter().watch() instead.');\n return watch.apply(this, arguments);\n },\n arrived: function(){\n console.warn('watch().arrived() is deprecated please use filter().watch() instead.');\n return watch.apply(this, arguments);\n },\n happened: function(){\n console.warn('watch().happened() is deprecated please use filter().watch() instead.');\n return watch.apply(this, arguments);\n },\n uninstall: function(){\n console.warn('watch().uninstall() is deprecated please use filter().stopWatching() instead.');\n return stopWatching.apply(this, arguments);\n },\n messages: function(){\n console.warn('watch().messages() is deprecated please use filter().get() instead.');\n return get.apply(this, arguments);\n },\n logs: function(){\n console.warn('watch().logs() is deprecated please use filter().get() instead.');\n return get.apply(this, arguments);\n }\n };\n};\n\nmodule.exports = filter;\n\n", + "/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/** @file filter.js\n * @authors:\n * Jeffrey Wilcke \n * Marek Kotewicz \n * Marian Oancea \n * Fabian Vogelsteller \n * Gav Wood \n * @date 2014\n */\n\nvar utils = require('../utils/utils');\n\n/// Should be called to check if filter implementation is valid\n/// @returns true if it is, otherwise false\nvar implementationIsValid = function (i) {\n return !!i && \n typeof i.newFilter === 'function' && \n typeof i.getLogs === 'function' && \n typeof i.uninstallFilter === 'function' &&\n typeof i.startPolling === 'function' &&\n typeof i.stopPolling === 'function';\n};\n\n/// This method should be called on options object, to verify deprecated properties && lazy load dynamic ones\n/// @param should be string or object\n/// @returns options string or object\nvar getOptions = function (options) {\n /*jshint maxcomplexity:9 */\n\n if (typeof options === 'string') {\n return options;\n } \n\n options = options || {};\n\n if (options.topic) {\n console.warn('\"topic\" is deprecated, is \"topics\" instead');\n options.topics = options.topic;\n }\n\n if (options.earliest) {\n console.warn('\"earliest\" is deprecated, is \"fromBlock\" instead');\n options.fromBlock = options.earliest;\n }\n\n if (options.latest) {\n console.warn('\"latest\" is deprecated, is \"toBlock\" instead');\n options.toBlock = options.latest;\n }\n\n // make sure topics, get converted to hex\n if(options.topics instanceof Array) {\n options.topics = options.topics.map(function(topic){\n return utils.toHex(topic);\n });\n }\n\n\tvar asBlockNumber = function(n) {\n\t\tif (n == null)\n\t\t\treturn null;\n\t\tif (n == 'latest' || n == 'pending')\n\t\t\treturn n;\n\t\treturn utils.toHex(n);\n\t};\n\n // evaluate lazy properties\n return {\n\t\tfromBlock: asBlockNumber(options.fromBlock),\n\t\ttoBlock: asBlockNumber(options.toBlock),\n to: options.to,\n address: options.address,\n topics: options.topics\n };\n};\n\n/// Should be used when we want to watch something\n/// it's using inner polling mechanism and is notified about changes\n/// @param options are filter options\n/// @param implementation, an abstract polling implementation\n/// @param formatter (optional), callback function which formats output before 'real' callback \nvar filter = function(options, implementation, formatter) {\n if (!implementationIsValid(implementation)) {\n console.error('filter implemenation is invalid');\n return;\n }\n\n options = getOptions(options);\n var callbacks = [];\n var filterId = implementation.newFilter(options);\n\n // call the callbacks\n var onMessages = function (messages) {\n messages.forEach(function (message) {\n\t\t\tmessage = formatter ? formatter(message) : message;\n callbacks.forEach(function (callback) {\n\t\t\t\tcallback(message);\n });\n });\n };\n\n implementation.startPolling(filterId, onMessages, implementation.uninstallFilter);\n\n var watch = function(callback) {\n callbacks.push(callback);\n };\n\n var stopWatching = function() {\n implementation.stopPolling(filterId);\n implementation.uninstallFilter(filterId);\n callbacks = [];\n };\n\n var get = function () {\n var results = implementation.getLogs(filterId);\n\n return utils.isArray(results) ? results.map(function(message){\n return formatter ? formatter(message) : message;\n }) : results;\n };\n \n return {\n watch: watch,\n stopWatching: stopWatching,\n get: get,\n\n // DEPRECATED methods\n changed: function(){\n console.warn('watch().changed() is deprecated please use filter().watch() instead.');\n return watch.apply(this, arguments);\n },\n arrived: function(){\n console.warn('watch().arrived() is deprecated please use filter().watch() instead.');\n return watch.apply(this, arguments);\n },\n happened: function(){\n console.warn('watch().happened() is deprecated please use filter().watch() instead.');\n return watch.apply(this, arguments);\n },\n uninstall: function(){\n console.warn('watch().uninstall() is deprecated please use filter().stopWatching() instead.');\n return stopWatching.apply(this, arguments);\n },\n messages: function(){\n console.warn('watch().messages() is deprecated please use filter().get() instead.');\n return get.apply(this, arguments);\n },\n logs: function(){\n console.warn('watch().logs() is deprecated please use filter().get() instead.');\n return get.apply(this, arguments);\n }\n };\n};\n\nmodule.exports = filter;\n\n", "/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/** @file formatters.js\n * @authors:\n * Marek Kotewicz \n * Fabian Vogelsteller \n * @date 2015\n */\n\nvar utils = require('../utils/utils');\n\n/**\n * Should the input to a big number\n *\n * @method convertToBigNumber\n * @param {String|Number|BigNumber}\n * @returns {BigNumber} object\n */\nvar convertToBigNumber = function (value) {\n return utils.toBigNumber(value);\n};\n\n/**\n * Formats the input of a transaction and converts all values to HEX\n *\n * @method inputTransactionFormatter\n * @param {Object} transaction options\n * @returns object\n*/\nvar inputTransactionFormatter = function (options){\n\n // make code -> data\n if (options.code) {\n options.data = options.code;\n delete options.code;\n }\n\n ['gasPrice', 'gas', 'value'].forEach(function(key){\n options[key] = utils.fromDecimal(options[key]);\n });\n\n return options;\n};\n\n/**\n * Formats the output of a transaction to its proper values\n * \n * @method outputTransactionFormatter\n * @param {Object} transaction\n * @returns {Object} transaction\n*/\nvar outputTransactionFormatter = function (tx){\n tx.gas = utils.toDecimal(tx.gas);\n tx.gasPrice = utils.toBigNumber(tx.gasPrice);\n tx.value = utils.toBigNumber(tx.value);\n return tx;\n};\n\n/**\n * Formats the input of a call and converts all values to HEX\n *\n * @method inputCallFormatter\n * @param {Object} transaction options\n * @returns object\n*/\nvar inputCallFormatter = function (options){\n\n // make code -> data\n if (options.code) {\n options.data = options.code;\n delete options.code;\n }\n\n return options;\n};\n\n\n/**\n * Formats the output of a block to its proper values\n *\n * @method outputBlockFormatter\n * @param {Object} block object \n * @returns {Object} block object\n*/\nvar outputBlockFormatter = function(block){\n\n // transform to number\n block.gasLimit = utils.toDecimal(block.gasLimit);\n block.gasUsed = utils.toDecimal(block.gasUsed);\n block.size = utils.toDecimal(block.size);\n block.timestamp = utils.toDecimal(block.timestamp);\n block.number = utils.toDecimal(block.number);\n\n block.minGasPrice = utils.toBigNumber(block.minGasPrice);\n block.difficulty = utils.toBigNumber(block.difficulty);\n block.totalDifficulty = utils.toBigNumber(block.totalDifficulty);\n\n if(block.transactions instanceof Array) {\n block.transactions.forEach(function(item){\n if(!utils.isString(item))\n return outputTransactionFormatter(item);\n });\n }\n\n return block;\n};\n\n/**\n * Formats the output of a log\n * \n * @method outputLogFormatter\n * @param {Object} log object\n * @returns {Object} log\n*/\nvar outputLogFormatter = function(log){\n log.blockNumber = utils.toDecimal(log.blockNumber);\n log.transactionIndex = utils.toDecimal(log.transactionIndex);\n log.logIndex = utils.toDecimal(log.logIndex);\n\n return log;\n};\n\n\n/**\n * Formats the input of a whisper post and converts all values to HEX\n *\n * @method inputPostFormatter\n * @param {Object} transaction object\n * @returns {Object}\n*/\nvar inputPostFormatter = function(post){\n\n post.payload = utils.toHex(post.payload);\n post.ttl = utils.fromDecimal(post.ttl);\n post.priority = utils.fromDecimal(post.priority);\n\n if(!(post.topics instanceof Array))\n post.topics = [post.topics];\n\n\n // format the following options\n post.topics = post.topics.map(function(topic){\n return utils.fromAscii(topic);\n });\n\n return post;\n};\n\n/**\n * Formats the output of a received post message\n *\n * @method outputPostFormatter\n * @param {Object}\n * @returns {Object}\n */\nvar outputPostFormatter = function(post){\n\n post.expiry = utils.toDecimal(post.expiry);\n post.sent = utils.toDecimal(post.sent);\n post.ttl = utils.toDecimal(post.ttl);\n post.workProved = utils.toDecimal(post.workProved);\n post.payloadRaw = post.payload;\n post.payload = utils.toAscii(post.payload);\n\n if(post.payload.indexOf('{') === 0 || post.payload.indexOf('[') === 0) {\n try {\n post.payload = JSON.parse(post.payload);\n } catch (e) { }\n }\n\n // format the following options\n post.topics = post.topics.map(function(topic){\n return utils.toAscii(topic);\n });\n\n return post;\n};\n\nmodule.exports = {\n convertToBigNumber: convertToBigNumber,\n inputTransactionFormatter: inputTransactionFormatter,\n outputTransactionFormatter: outputTransactionFormatter,\n inputCallFormatter: inputCallFormatter,\n outputBlockFormatter: outputBlockFormatter,\n outputLogFormatter: outputLogFormatter,\n inputPostFormatter: inputPostFormatter,\n outputPostFormatter: outputPostFormatter\n};\n\n", "/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/** @file httpprovider.js\n * @authors:\n * Marek Kotewicz \n * Marian Oancea \n * Fabian Vogelsteller \n * @date 2014\n */\n\nif (\"build\" !== 'build') {/*\n var XMLHttpRequest = require('xmlhttprequest').XMLHttpRequest; // jshint ignore:line\n*/}\n\nvar HttpProvider = function (host) {\n this.name = 'HTTP';\n this.handlers = [];\n this.host = host || 'http://localhost:8080';\n};\n\nHttpProvider.prototype.send = function (payload, callback) {\n var request = new XMLHttpRequest();\n\n // ASYNC\n if(typeof callback === 'function') {\n request.onreadystatechange = function() {\n if(request.readyState === 4) {\n var result = '';\n try {\n result = JSON.parse(request.responseText);\n } catch(error) {\n result = error;\n }\n callback(result, request.status);\n }\n };\n\n request.open('POST', this.host, true);\n request.send(JSON.stringify(payload));\n\n // SYNC\n } else {\n request.open('POST', this.host, false);\n request.send(JSON.stringify(payload));\n\n // check request.status\n if(request.status !== 200)\n return;\n return JSON.parse(request.responseText);\n \n }\n};\n\nmodule.exports = HttpProvider;\n\n", "/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/** @file jsonrpc.js\n * @authors:\n * Marek Kotewicz \n * @date 2015\n */\n\nvar messageId = 1;\n\n/// Should be called to valid json create payload object\n/// @param method of jsonrpc call, required\n/// @param params, an array of method params, optional\n/// @returns valid jsonrpc payload object\nvar toPayload = function (method, params) {\n if (!method)\n console.error('jsonrpc method should be specified!');\n\n return {\n jsonrpc: '2.0',\n method: method,\n params: params || [],\n id: messageId++\n }; \n};\n\n/// Should be called to check if jsonrpc response is valid\n/// @returns true if response is valid, otherwise false \nvar isValidResponse = function (response) {\n return !!response &&\n !response.error &&\n response.jsonrpc === '2.0' &&\n typeof response.id === 'number' &&\n response.result !== undefined; // only undefined is not valid json object\n};\n\n/// Should be called to create batch payload object\n/// @param messages, an array of objects with method (required) and params (optional) fields\nvar toBatchPayload = function (messages) {\n return messages.map(function (message) {\n return toPayload(message.method, message.params);\n }); \n};\n\nmodule.exports = {\n toPayload: toPayload,\n isValidResponse: isValidResponse,\n toBatchPayload: toBatchPayload\n};\n\n\n", diff --git a/libjsqrc/ethereumjs/dist/ethereum.min.js b/libjsqrc/ethereumjs/dist/ethereum.min.js index fd56cc979..4aab986d6 100644 --- a/libjsqrc/ethereumjs/dist/ethereum.min.js +++ b/libjsqrc/ethereumjs/dist/ethereum.min.js @@ -1 +1 @@ -require=function t(e,n,r){function o(a,u){if(!n[a]){if(!e[a]){var s="function"==typeof require&&require;if(!u&&s)return s(a,!0);if(i)return i(a,!0);var c=new Error("Cannot find module '"+a+"'");throw c.code="MODULE_NOT_FOUND",c}var l=n[a]={exports:{}};e[a][0].call(l.exports,function(t){var n=e[a][1][t];return o(n?n:t)},l,l.exports,t,e,n,r)}return n[a].exports}for(var i="function"==typeof require&&require,a=0;ay;y++)g.push(d(e.slice(0,s))),e=e.slice(s);n.push(g)}else o.prefixedType("bytes")(t[c].type)?(l=l.slice(s),n.push(d(e.slice(0,s))),e=e.slice(s)):(n.push(d(e.slice(0,s))),e=e.slice(s))}),n},d=function(t){var e={};return t.forEach(function(t){var r=n.extractDisplayName(t.name),o=n.extractTypeName(t.name),i=function(){var e=Array.prototype.slice.call(arguments);return l(t.inputs,e)};void 0===e[r]&&(e[r]=i),e[r][o]=i}),e},h=function(t){var e={};return t.forEach(function(t){var r=n.extractDisplayName(t.name),o=n.extractTypeName(t.name),i=function(e){return m(t.outputs,e)};void 0===e[r]&&(e[r]=i),e[r][o]=i}),e};e.exports={inputParser:d,outputParser:h,formatInput:l,formatOutput:m}},{"../utils/config":4,"../utils/utils":5,"./formatters":2,"./types":3}],2:[function(t,e){var n=t("../utils/utils"),r=t("../utils/config"),o=function(t,e,n){return new Array(e-t.length+1).join(n?n:"0")+t},i=function(t){var e=2*r.ETH_PADDING;return BigNumber.config(r.ETH_BIGNUMBER_ROUNDING_MODE),o(n.toTwosComplement(t).round().toString(16),e)},a=function(t){return n.fromAscii(t,r.ETH_PADDING).substr(2)},u=function(t){return"000000000000000000000000000000000000000000000000000000000000000"+(t?"1":"0")},s=function(t){return i(new BigNumber(t).times(new BigNumber(2).pow(128)))},c=function(t){return"1"===new BigNumber(t.substr(0,1),16).toString(2).substr(0,1)},l=function(t){return t=t||"0",c(t)?new BigNumber(t,16).minus(new BigNumber("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",16)).minus(1):new BigNumber(t,16)},f=function(t){return t=t||"0",new BigNumber(t,16)},p=function(t){return l(t).dividedBy(new BigNumber(2).pow(128))},m=function(t){return f(t).dividedBy(new BigNumber(2).pow(128))},d=function(t){return"0x"+t},h=function(t){return"0000000000000000000000000000000000000000000000000000000000000001"===t?!0:!1},g=function(t){return n.toAscii(t)},y=function(t){return"0x"+t.slice(t.length-40,t.length)};e.exports={formatInputInt:i,formatInputString:a,formatInputBool:u,formatInputReal:s,formatOutputInt:l,formatOutputUInt:f,formatOutputReal:p,formatOutputUReal:m,formatOutputHash:d,formatOutputBool:h,formatOutputString:g,formatOutputAddress:y}},{"../utils/config":4,"../utils/utils":5}],3:[function(t,e){var n=t("./formatters"),r=function(t){return function(e){return 0===e.indexOf(t)}},o=function(t){return function(e){return t===e}},i=function(){return[{type:r("uint"),format:n.formatInputInt},{type:r("int"),format:n.formatInputInt},{type:r("bytes"),format:n.formatInputString},{type:r("real"),format:n.formatInputReal},{type:r("ureal"),format:n.formatInputReal},{type:o("address"),format:n.formatInputInt},{type:o("bool"),format:n.formatInputBool}]},a=function(){return[{type:r("uint"),format:n.formatOutputUInt},{type:r("int"),format:n.formatOutputInt},{type:r("bytes"),format:n.formatOutputString},{type:r("real"),format:n.formatOutputReal},{type:r("ureal"),format:n.formatOutputUReal},{type:o("address"),format:n.formatOutputAddress},{type:o("bool"),format:n.formatOutputBool}]};e.exports={prefixedType:r,namedType:o,inputTypes:i,outputTypes:a}},{"./formatters":2}],4:[function(t,e){var n=["wei","Kwei","Mwei","Gwei","szabo","finney","ether","grand","Mether","Gether","Tether","Pether","Eether","Zether","Yether","Nether","Dether","Vether","Uether"];e.exports={ETH_PADDING:32,ETH_SIGNATURE_LENGTH:4,ETH_UNITS:n,ETH_BIGNUMBER_ROUNDING_MODE:{ROUNDING_MODE:BigNumber.ROUND_DOWN},ETH_POLLING_TIMEOUT:1e3,ETH_DEFAULTBLOCK:"latest"}},{}],5:[function(t,e){var n={wei:"1",kwei:"1000",ada:"1000",mwei:"1000000",babbage:"1000000",gwei:"1000000000",shannon:"1000000000",szabo:"1000000000000",finney:"1000000000000000",ether:"1000000000000000000",kether:"1000000000000000000000",grand:"1000000000000000000000",einstein:"1000000000000000000000",mether:"1000000000000000000000000",gether:"1000000000000000000000000000",tether:"1000000000000000000000000000000"},r=function(t,e){for(var n=!1,r=0;rn;n+=2){var o=parseInt(t.substr(n,2),16);if(0===o)break;e+=String.fromCharCode(o)}return e},i=function(t){for(var e="",n=0;n1?(t[n[0]]||(t[n[0]]={}),t[n[0]][n[1]]=r):t[n[0]]=r})},g=function(t,e){e.forEach(function(e){var n=e.name.split("."),r={};r.get=function(){return e.newProperty&&console.warn("This property is deprecated please use web3."+e.newProperty+" instead."),_.manager.send({method:e.getter,outputFormatter:e.outputFormatter})},e.setter&&(r.set=function(t){return e.newProperty&&console.warn("This property is deprecated please use web3."+e.newProperty+" instead."),_.manager.send({method:e.setter,params:[t],inputFormatter:e.inputFormatter})}),r.enumerable=!e.newProperty,n.length>1?(t[n[0]]||(t[n[0]]={}),Object.defineProperty(t[n[0]],n[1],r)):Object.defineProperty(t,e.name,r)})},y=function(t,e,n,r){_.manager.startPolling({method:t,params:[e]},e,n,r)},b=function(t){_.manager.stopPolling(t)},v={startPolling:y.bind(null,"eth_getFilterChanges"),stopPolling:b},w={startPolling:y.bind(null,"shh_getFilterChanges"),stopPolling:b},_={version:{api:n.version},manager:f(),providers:{},setProvider:function(t){_.manager.setProvider(t)},reset:function(){_.manager.reset()},toHex:c.toHex,toAscii:c.toAscii,fromAscii:c.fromAscii,toDecimal:c.toDecimal,fromDecimal:c.fromDecimal,toBigNumber:c.toBigNumber,toWei:c.toWei,fromWei:c.fromWei,isAddress:c.isAddress,net:{},eth:{contractFromAbi:function(t){return console.warn("Initiating a contract like this is deprecated please use var MyContract = eth.contract(abi); new MyContract(address); instead."),function(e){e=e||"0xc6d9d2cd449a754c494264e1809c50e34d64562b";var n=_.eth.contract(e,t);return n.address=e,n}},filter:function(t,e,n){return t._isEvent?t(e,n):s(t,v,l.outputLogFormatter)},watch:function(t,e,n){return console.warn("eth.watch() is deprecated please use eth.filter() instead."),this.filter(t,e,n)}},db:{},shh:{filter:function(t){return s(t,w,l.outputPostFormatter)},watch:function(t){return console.warn("shh.watch() is deprecated please use shh.filter() instead."),this.filter(t)}}};Object.defineProperty(_.eth,"defaultBlock",{get:function(){return p.ETH_DEFAULTBLOCK},set:function(t){return p.ETH_DEFAULTBLOCK=t,p.ETH_DEFAULTBLOCK}}),h(_,m),g(_,d),h(_.net,r.methods),g(_.net,r.properties),h(_.eth,o.methods),g(_.eth,o.properties),h(_.db,i.methods()),h(_.shh,a.methods()),h(v,u.eth()),h(w,u.shh()),e.exports=_},{"../version.json":21,"./solidity/formatters":2,"./utils/config":4,"./utils/utils":5,"./web3/db":8,"./web3/eth":9,"./web3/filter":11,"./web3/net":15,"./web3/requestmanager":17,"./web3/shh":18,"./web3/watches":20}],7:[function(t,e){function n(t,e){t.forEach(function(t){if(-1===t.name.indexOf("(")){var e=t.name,n=t.inputs.map(function(t){return t.type}).join();t.name=e+"("+n+")"}});var n={};return c(n),l(n,t,e),f(n,t,e),p(n,t,e),n}var r=t("../web3"),o=t("../solidity/abi"),i=t("../utils/utils"),a=t("./event"),u=t("./signature"),s=function(t){r._currentContractAbi=t.abi,r._currentContractAddress=t.address,r._currentContractMethodName=t.method,r._currentContractMethodParams=t.params},c=function(t){t.call=function(e){return t._isTransaction=!1,t._options=e,t},t.sendTransaction=function(e){return t._isTransaction=!0,t._options=e,t},t.transact=function(e){return console.warn("myContract.transact() is deprecated please use myContract.sendTransaction() instead."),t.sendTransaction(e)},t._options={},["gas","gasPrice","value","from"].forEach(function(e){t[e]=function(n){return t._options[e]=n,t}})},l=function(t,e,n){var a=o.inputParser(e),c=o.outputParser(e);i.filterFunctions(e).forEach(function(o){var l=i.extractDisplayName(o.name),f=i.extractTypeName(o.name),p=function(){var i=Array.prototype.slice.call(arguments),p=u.functionSignatureFromAscii(o.name),m=a[l][f].apply(null,i),d=t._options||{};d.to=n,d.data=p+m;var h=t._isTransaction===!0||t._isTransaction!==!1&&!o.constant,g=d.collapse!==!1;if(t._options={},t._isTransaction=null,h)return s({abi:e,address:n,method:o.name,params:i}),void r.eth.sendTransaction(d);var y=r.eth.call(d),b=c[l][f](y);return g&&(1===b.length?b=b[0]:0===b.length&&(b=null)),b};void 0===t[l]&&(t[l]=p),t[l][f]=p})},f=function(t,e,n){t.address=n,t._onWatchEventResult=function(t){var n=event.getMatchingEvent(i.filterEvents(e)),r=a.outputParser(n);return r(t)},Object.defineProperty(t,"topics",{get:function(){return i.filterEvents(e).map(function(t){return u.eventSignatureFromAscii(t.name)})}})},p=function(t,e,n){i.filterEvents(e).forEach(function(e){var o=function(){var t=Array.prototype.slice.call(arguments),o=u.eventSignatureFromAscii(e.name),i=a.inputParser(n,o,e),s=i.apply(null,t),c=function(t){var n=a.outputParser(e);return n(t)};return r.eth.filter(s,void 0,void 0,c)};o._isEvent=!0;var s=i.extractDisplayName(e.name),c=i.extractTypeName(e.name);void 0===t[s]&&(t[s]=o),t[s][c]=o})},m=function(t){return t instanceof Array&&1===arguments.length?n.bind(null,t):(console.warn("Initiating a contract like this is deprecated please use var MyContract = eth.contract(abi); new MyContract(address); instead."),new n(arguments[1],arguments[0]))};e.exports=m},{"../solidity/abi":1,"../utils/utils":5,"../web3":6,"./event":10,"./signature":19}],8:[function(t,e){var n=function(){return[{name:"putString",call:"db_putString"},{name:"getString",call:"db_getString"},{name:"putHex",call:"db_putHex"},{name:"getHex",call:"db_getHex"}]};e.exports={methods:n}},{}],9:[function(t,e){var n=t("./formatters"),r=t("../utils/utils"),o=function(t){return r.isString(t[0])&&0===t[0].indexOf("0x")?"eth_getBlockByHash":"eth_getBlockByNumber"},i=function(t){return r.isString(t[0])&&0===t[0].indexOf("0x")?"eth_getTransactionByBlockHashAndIndex":"eth_getTransactionByBlockNumberAndIndex"},a=function(t){return r.isString(t[0])&&0===t[0].indexOf("0x")?"eth_getUncleByBlockHashAndIndex":"eth_getUncleByBlockNumberAndIndex"},u=function(t){return r.isString(t[0])&&0===t[0].indexOf("0x")?"eth_getBlockTransactionCountByHash":"eth_getBlockTransactionCountByNumber"},s=function(t){return r.isString(t[0])&&0===t[0].indexOf("0x")?"eth_getUncleCountByBlockHash":"eth_getUncleCountByBlockNumber"},c=[{name:"getBalance",call:"eth_getBalance",addDefaultblock:2,outputFormatter:n.convertToBigNumber},{name:"getStorageAt",call:"eth_getStorageAt",addDefaultblock:3,inputFormatter:r.toHex},{name:"getCode",call:"eth_getCode",addDefaultblock:2},{name:"getBlock",call:o,outputFormatter:n.outputBlockFormatter,inputFormatter:[r.toHex,function(t){return t?!0:!1}]},{name:"getUncle",call:a,outputFormatter:n.outputBlockFormatter,inputFormatter:[r.toHex,r.toHex,function(t){return t?!0:!1}]},{name:"getCompilers",call:"eth_getCompilers"},{name:"getBlockTransactionCount",call:u,outputFormatter:r.toDecimal,inputFormatter:r.toHex},{name:"getBlockUncleCount",call:s,outputFormatter:r.toDecimal,inputFormatter:r.toHex},{name:"getTransaction",call:"eth_getTransactionByHash",outputFormatter:n.outputTransactionFormatter},{name:"getTransactionFromBlock",call:i,outputFormatter:n.outputTransactionFormatter,inputFormatter:r.toHex},{name:"getTransactionCount",call:"eth_getTransactionCount",addDefaultblock:2,outputFormatter:r.toDecimal},{name:"sendTransaction",call:"eth_sendTransaction",inputFormatter:n.inputTransactionFormatter},{name:"call",call:"eth_call",addDefaultblock:2,inputFormatter:n.inputCallFormatter},{name:"compile.solidity",call:"eth_compileSolidity"},{name:"compile.lll",call:"eth_compileLLL",inputFormatter:r.toHex},{name:"compile.serpent",call:"eth_compileSerpent",inputFormatter:r.toHex},{name:"flush",call:"eth_flush"},{name:"balanceAt",call:"eth_balanceAt",newMethod:"eth.getBalance"},{name:"stateAt",call:"eth_stateAt",newMethod:"eth.getStorageAt"},{name:"storageAt",call:"eth_storageAt",newMethod:"eth.getStorage"},{name:"countAt",call:"eth_countAt",newMethod:"eth.getTransactionCount"},{name:"codeAt",call:"eth_codeAt",newMethod:"eth.getCode"},{name:"transact",call:"eth_transact",newMethod:"eth.sendTransaction"},{name:"block",call:o,newMethod:"eth.getBlock"},{name:"transaction",call:i,newMethod:"eth.getTransaction"},{name:"uncle",call:a,newMethod:"eth.getUncle"},{name:"compilers",call:"eth_compilers",newMethod:"eth.getCompilers"},{name:"solidity",call:"eth_solidity",newMethod:"eth.compile.solidity"},{name:"lll",call:"eth_lll",newMethod:"eth.compile.lll"},{name:"serpent",call:"eth_serpent",newMethod:"eth.compile.serpent"},{name:"transactionCount",call:u,newMethod:"eth.getBlockTransactionCount"},{name:"uncleCount",call:s,newMethod:"eth.getBlockUncleCount"},{name:"logs",call:"eth_logs"}],l=[{name:"coinbase",getter:"eth_coinbase"},{name:"mining",getter:"eth_mining"},{name:"gasPrice",getter:"eth_gasPrice",outputFormatter:n.convertToBigNumber},{name:"accounts",getter:"eth_accounts"},{name:"blockNumber",getter:"eth_blockNumber",outputFormatter:r.toDecimal},{name:"listening",getter:"net_listening",setter:"eth_setListening",newProperty:"net.listening"},{name:"peerCount",getter:"net_peerCount",newProperty:"net.peerCount"},{name:"number",getter:"eth_number",newProperty:"eth.blockNumber"}];e.exports={methods:c,properties:l}},{"../utils/utils":5,"./formatters":12}],10:[function(t,e){var n=t("../solidity/abi"),r=t("../utils/utils"),o=t("./signature"),i=function(t,e){return t.filter(function(t){return t.indexed===e})},a=function(t,e){var n=r.findIndex(t,function(t){return t.name===e});return-1===n?void console.error("indexed param with name "+e+" not found"):t[n]},u=function(t,e){return Object.keys(e).map(function(r){var o=[a(i(t.inputs,!0),r)],u=e[r];return u instanceof Array?u.map(function(t){return n.formatInput(o,[t])}):n.formatInput(o,[u])})},s=function(t,e,n){return function(r,o){var i=o||{};return i.address=t,i.topics=[],i.topics.push(e),r&&(i.topics=i.topics.concat(u(n,r))),i}},c=function(t,e,n){var r=e.slice(),o=n.slice();return t.reduce(function(t,e){var n;return n=e.indexed?r.splice(0,1)[0]:o.splice(0,1)[0],t[e.name]=n,t},{})},l=function(t){return function(e){var o={event:r.extractDisplayName(t.name),number:e.number,hash:e.hash,args:{}};if(e.topics=e.topic,!e.topics)return o;var a=i(t.inputs,!0),u="0x"+e.topics.slice(1,e.topics.length).map(function(t){return t.slice(2)}).join(""),s=n.formatOutput(a,u),l=i(t.inputs,!1),f=n.formatOutput(l,e.data);return o.args=c(t.inputs,s,f),o}},f=function(t,e){for(var n=0;ny;y++)g.push(d(e.slice(0,s))),e=e.slice(s);n.push(g)}else o.prefixedType("bytes")(t[c].type)?(l=l.slice(s),n.push(d(e.slice(0,s))),e=e.slice(s)):(n.push(d(e.slice(0,s))),e=e.slice(s))}),n},d=function(t){var e={};return t.forEach(function(t){var r=n.extractDisplayName(t.name),o=n.extractTypeName(t.name),i=function(){var e=Array.prototype.slice.call(arguments);return l(t.inputs,e)};void 0===e[r]&&(e[r]=i),e[r][o]=i}),e},h=function(t){var e={};return t.forEach(function(t){var r=n.extractDisplayName(t.name),o=n.extractTypeName(t.name),i=function(e){return m(t.outputs,e)};void 0===e[r]&&(e[r]=i),e[r][o]=i}),e};e.exports={inputParser:d,outputParser:h,formatInput:l,formatOutput:m}},{"../utils/config":4,"../utils/utils":5,"./formatters":2,"./types":3}],2:[function(t,e){var n=t("../utils/utils"),r=t("../utils/config"),o=function(t,e,n){return new Array(e-t.length+1).join(n?n:"0")+t},i=function(t){var e=2*r.ETH_PADDING;return BigNumber.config(r.ETH_BIGNUMBER_ROUNDING_MODE),o(n.toTwosComplement(t).round().toString(16),e)},a=function(t){return n.fromAscii(t,r.ETH_PADDING).substr(2)},u=function(t){return"000000000000000000000000000000000000000000000000000000000000000"+(t?"1":"0")},s=function(t){return i(new BigNumber(t).times(new BigNumber(2).pow(128)))},c=function(t){return"1"===new BigNumber(t.substr(0,1),16).toString(2).substr(0,1)},l=function(t){return t=t||"0",c(t)?new BigNumber(t,16).minus(new BigNumber("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",16)).minus(1):new BigNumber(t,16)},f=function(t){return t=t||"0",new BigNumber(t,16)},p=function(t){return l(t).dividedBy(new BigNumber(2).pow(128))},m=function(t){return f(t).dividedBy(new BigNumber(2).pow(128))},d=function(t){return"0x"+t},h=function(t){return"0000000000000000000000000000000000000000000000000000000000000001"===t?!0:!1},g=function(t){return n.toAscii(t)},y=function(t){return"0x"+t.slice(t.length-40,t.length)};e.exports={formatInputInt:i,formatInputString:a,formatInputBool:u,formatInputReal:s,formatOutputInt:l,formatOutputUInt:f,formatOutputReal:p,formatOutputUReal:m,formatOutputHash:d,formatOutputBool:h,formatOutputString:g,formatOutputAddress:y}},{"../utils/config":4,"../utils/utils":5}],3:[function(t,e){var n=t("./formatters"),r=function(t){return function(e){return 0===e.indexOf(t)}},o=function(t){return function(e){return t===e}},i=function(){return[{type:r("uint"),format:n.formatInputInt},{type:r("int"),format:n.formatInputInt},{type:r("bytes"),format:n.formatInputString},{type:r("real"),format:n.formatInputReal},{type:r("ureal"),format:n.formatInputReal},{type:o("address"),format:n.formatInputInt},{type:o("bool"),format:n.formatInputBool}]},a=function(){return[{type:r("uint"),format:n.formatOutputUInt},{type:r("int"),format:n.formatOutputInt},{type:r("bytes"),format:n.formatOutputString},{type:r("real"),format:n.formatOutputReal},{type:r("ureal"),format:n.formatOutputUReal},{type:o("address"),format:n.formatOutputAddress},{type:o("bool"),format:n.formatOutputBool}]};e.exports={prefixedType:r,namedType:o,inputTypes:i,outputTypes:a}},{"./formatters":2}],4:[function(t,e){var n=["wei","Kwei","Mwei","Gwei","szabo","finney","ether","grand","Mether","Gether","Tether","Pether","Eether","Zether","Yether","Nether","Dether","Vether","Uether"];e.exports={ETH_PADDING:32,ETH_SIGNATURE_LENGTH:4,ETH_UNITS:n,ETH_BIGNUMBER_ROUNDING_MODE:{ROUNDING_MODE:BigNumber.ROUND_DOWN},ETH_POLLING_TIMEOUT:1e3,ETH_DEFAULTBLOCK:"latest"}},{}],5:[function(t,e){var n={wei:"1",kwei:"1000",ada:"1000",mwei:"1000000",babbage:"1000000",gwei:"1000000000",shannon:"1000000000",szabo:"1000000000000",finney:"1000000000000000",ether:"1000000000000000000",kether:"1000000000000000000000",grand:"1000000000000000000000",einstein:"1000000000000000000000",mether:"1000000000000000000000000",gether:"1000000000000000000000000000",tether:"1000000000000000000000000000000"},r=function(t,e){for(var n=!1,r=0;rn;n+=2){var o=parseInt(t.substr(n,2),16);if(0===o)break;e+=String.fromCharCode(o)}return e},i=function(t){for(var e="",n=0;n1?(t[n[0]]||(t[n[0]]={}),t[n[0]][n[1]]=r):t[n[0]]=r})},g=function(t,e){e.forEach(function(e){var n=e.name.split("."),r={};r.get=function(){return e.newProperty&&console.warn("This property is deprecated please use web3."+e.newProperty+" instead."),_.manager.send({method:e.getter,outputFormatter:e.outputFormatter})},e.setter&&(r.set=function(t){return e.newProperty&&console.warn("This property is deprecated please use web3."+e.newProperty+" instead."),_.manager.send({method:e.setter,params:[t],inputFormatter:e.inputFormatter})}),r.enumerable=!e.newProperty,n.length>1?(t[n[0]]||(t[n[0]]={}),Object.defineProperty(t[n[0]],n[1],r)):Object.defineProperty(t,e.name,r)})},y=function(t,e,n,r){_.manager.startPolling({method:t,params:[e]},e,n,r)},b=function(t){_.manager.stopPolling(t)},v={startPolling:y.bind(null,"eth_getFilterChanges"),stopPolling:b},w={startPolling:y.bind(null,"shh_getFilterChanges"),stopPolling:b},_={version:{api:n.version},manager:f(),providers:{},setProvider:function(t){_.manager.setProvider(t)},reset:function(){_.manager.reset()},toHex:c.toHex,toAscii:c.toAscii,fromAscii:c.fromAscii,toDecimal:c.toDecimal,fromDecimal:c.fromDecimal,toBigNumber:c.toBigNumber,toWei:c.toWei,fromWei:c.fromWei,isAddress:c.isAddress,net:{},eth:{contractFromAbi:function(t){return console.warn("Initiating a contract like this is deprecated please use var MyContract = eth.contract(abi); new MyContract(address); instead."),function(e){e=e||"0xc6d9d2cd449a754c494264e1809c50e34d64562b";var n=_.eth.contract(e,t);return n.address=e,n}},filter:function(t,e,n){return t._isEvent?t(e,n):s(t,v,l.outputLogFormatter)},watch:function(t,e,n){return console.warn("eth.watch() is deprecated please use eth.filter() instead."),this.filter(t,e,n)}},db:{},shh:{filter:function(t){return s(t,w,l.outputPostFormatter)},watch:function(t){return console.warn("shh.watch() is deprecated please use shh.filter() instead."),this.filter(t)}}};Object.defineProperty(_.eth,"defaultBlock",{get:function(){return p.ETH_DEFAULTBLOCK},set:function(t){return p.ETH_DEFAULTBLOCK=t,p.ETH_DEFAULTBLOCK}}),h(_,m),g(_,d),h(_.net,r.methods),g(_.net,r.properties),h(_.eth,o.methods),g(_.eth,o.properties),h(_.db,i.methods()),h(_.shh,a.methods()),h(v,u.eth()),h(w,u.shh()),e.exports=_},{"../version.json":21,"./solidity/formatters":2,"./utils/config":4,"./utils/utils":5,"./web3/db":8,"./web3/eth":9,"./web3/filter":11,"./web3/net":15,"./web3/requestmanager":17,"./web3/shh":18,"./web3/watches":20}],7:[function(t,e){function n(t,e){t.forEach(function(t){if(-1===t.name.indexOf("(")){var e=t.name,n=t.inputs.map(function(t){return t.type}).join();t.name=e+"("+n+")"}});var n={};return c(n),l(n,t,e),f(n,t,e),p(n,t,e),n}var r=t("../web3"),o=t("../solidity/abi"),i=t("../utils/utils"),a=t("./event"),u=t("./signature"),s=function(t){r._currentContractAbi=t.abi,r._currentContractAddress=t.address,r._currentContractMethodName=t.method,r._currentContractMethodParams=t.params},c=function(t){t.call=function(e){return t._isTransaction=!1,t._options=e,t},t.sendTransaction=function(e){return t._isTransaction=!0,t._options=e,t},t.transact=function(e){return console.warn("myContract.transact() is deprecated please use myContract.sendTransaction() instead."),t.sendTransaction(e)},t._options={},["gas","gasPrice","value","from"].forEach(function(e){t[e]=function(n){return t._options[e]=n,t}})},l=function(t,e,n){var a=o.inputParser(e),c=o.outputParser(e);i.filterFunctions(e).forEach(function(o){var l=i.extractDisplayName(o.name),f=i.extractTypeName(o.name),p=function(){var i=Array.prototype.slice.call(arguments),p=u.functionSignatureFromAscii(o.name),m=a[l][f].apply(null,i),d=t._options||{};d.to=n,d.data=p+m;var h=t._isTransaction===!0||t._isTransaction!==!1&&!o.constant,g=d.collapse!==!1;if(t._options={},t._isTransaction=null,h)return s({abi:e,address:n,method:o.name,params:i}),void r.eth.sendTransaction(d);var y=r.eth.call(d),b=c[l][f](y);return g&&(1===b.length?b=b[0]:0===b.length&&(b=null)),b};void 0===t[l]&&(t[l]=p),t[l][f]=p})},f=function(t,e,n){t.address=n,t._onWatchEventResult=function(t){var n=event.getMatchingEvent(i.filterEvents(e)),r=a.outputParser(n);return r(t)},Object.defineProperty(t,"topics",{get:function(){return i.filterEvents(e).map(function(t){return u.eventSignatureFromAscii(t.name)})}})},p=function(t,e,n){i.filterEvents(e).forEach(function(e){var o=function(){var t=Array.prototype.slice.call(arguments),o=u.eventSignatureFromAscii(e.name),i=a.inputParser(n,o,e),s=i.apply(null,t),c=function(t){var n=a.outputParser(e);return n(t)};return r.eth.filter(s,void 0,void 0,c)};o._isEvent=!0;var s=i.extractDisplayName(e.name),c=i.extractTypeName(e.name);void 0===t[s]&&(t[s]=o),t[s][c]=o})},m=function(t){return t instanceof Array&&1===arguments.length?n.bind(null,t):(console.warn("Initiating a contract like this is deprecated please use var MyContract = eth.contract(abi); new MyContract(address); instead."),new n(arguments[1],arguments[0]))};e.exports=m},{"../solidity/abi":1,"../utils/utils":5,"../web3":6,"./event":10,"./signature":19}],8:[function(t,e){var n=function(){return[{name:"putString",call:"db_putString"},{name:"getString",call:"db_getString"},{name:"putHex",call:"db_putHex"},{name:"getHex",call:"db_getHex"}]};e.exports={methods:n}},{}],9:[function(t,e){var n=t("./formatters"),r=t("../utils/utils"),o=function(t){return r.isString(t[0])&&0===t[0].indexOf("0x")?"eth_getBlockByHash":"eth_getBlockByNumber"},i=function(t){return r.isString(t[0])&&0===t[0].indexOf("0x")?"eth_getTransactionByBlockHashAndIndex":"eth_getTransactionByBlockNumberAndIndex"},a=function(t){return r.isString(t[0])&&0===t[0].indexOf("0x")?"eth_getUncleByBlockHashAndIndex":"eth_getUncleByBlockNumberAndIndex"},u=function(t){return r.isString(t[0])&&0===t[0].indexOf("0x")?"eth_getBlockTransactionCountByHash":"eth_getBlockTransactionCountByNumber"},s=function(t){return r.isString(t[0])&&0===t[0].indexOf("0x")?"eth_getUncleCountByBlockHash":"eth_getUncleCountByBlockNumber"},c=[{name:"getBalance",call:"eth_getBalance",addDefaultblock:2,outputFormatter:n.convertToBigNumber},{name:"getStorageAt",call:"eth_getStorageAt",addDefaultblock:3,inputFormatter:r.toHex},{name:"getCode",call:"eth_getCode",addDefaultblock:2},{name:"getBlock",call:o,outputFormatter:n.outputBlockFormatter,inputFormatter:[r.toHex,function(t){return t?!0:!1}]},{name:"getUncle",call:a,outputFormatter:n.outputBlockFormatter,inputFormatter:[r.toHex,r.toHex,function(t){return t?!0:!1}]},{name:"getCompilers",call:"eth_getCompilers"},{name:"getBlockTransactionCount",call:u,outputFormatter:r.toDecimal,inputFormatter:r.toHex},{name:"getBlockUncleCount",call:s,outputFormatter:r.toDecimal,inputFormatter:r.toHex},{name:"getTransaction",call:"eth_getTransactionByHash",outputFormatter:n.outputTransactionFormatter},{name:"getTransactionFromBlock",call:i,outputFormatter:n.outputTransactionFormatter,inputFormatter:r.toHex},{name:"getTransactionCount",call:"eth_getTransactionCount",addDefaultblock:2,outputFormatter:r.toDecimal},{name:"sendTransaction",call:"eth_sendTransaction",inputFormatter:n.inputTransactionFormatter},{name:"call",call:"eth_call",addDefaultblock:2,inputFormatter:n.inputCallFormatter},{name:"compile.solidity",call:"eth_compileSolidity"},{name:"compile.lll",call:"eth_compileLLL",inputFormatter:r.toHex},{name:"compile.serpent",call:"eth_compileSerpent",inputFormatter:r.toHex},{name:"flush",call:"eth_flush"},{name:"balanceAt",call:"eth_balanceAt",newMethod:"eth.getBalance"},{name:"stateAt",call:"eth_stateAt",newMethod:"eth.getStorageAt"},{name:"storageAt",call:"eth_storageAt",newMethod:"eth.getStorage"},{name:"countAt",call:"eth_countAt",newMethod:"eth.getTransactionCount"},{name:"codeAt",call:"eth_codeAt",newMethod:"eth.getCode"},{name:"transact",call:"eth_transact",newMethod:"eth.sendTransaction"},{name:"block",call:o,newMethod:"eth.getBlock"},{name:"transaction",call:i,newMethod:"eth.getTransaction"},{name:"uncle",call:a,newMethod:"eth.getUncle"},{name:"compilers",call:"eth_compilers",newMethod:"eth.getCompilers"},{name:"solidity",call:"eth_solidity",newMethod:"eth.compile.solidity"},{name:"lll",call:"eth_lll",newMethod:"eth.compile.lll"},{name:"serpent",call:"eth_serpent",newMethod:"eth.compile.serpent"},{name:"transactionCount",call:u,newMethod:"eth.getBlockTransactionCount"},{name:"uncleCount",call:s,newMethod:"eth.getBlockUncleCount"},{name:"logs",call:"eth_logs"}],l=[{name:"coinbase",getter:"eth_coinbase"},{name:"mining",getter:"eth_mining"},{name:"gasPrice",getter:"eth_gasPrice",outputFormatter:n.convertToBigNumber},{name:"accounts",getter:"eth_accounts"},{name:"blockNumber",getter:"eth_blockNumber",outputFormatter:r.toDecimal},{name:"listening",getter:"net_listening",setter:"eth_setListening",newProperty:"net.listening"},{name:"peerCount",getter:"net_peerCount",newProperty:"net.peerCount"},{name:"number",getter:"eth_number",newProperty:"eth.blockNumber"}];e.exports={methods:c,properties:l}},{"../utils/utils":5,"./formatters":12}],10:[function(t,e){var n=t("../solidity/abi"),r=t("../utils/utils"),o=t("./signature"),i=function(t,e){return t.filter(function(t){return t.indexed===e})},a=function(t,e){var n=r.findIndex(t,function(t){return t.name===e});return-1===n?void console.error("indexed param with name "+e+" not found"):t[n]},u=function(t,e){return Object.keys(e).map(function(r){var o=[a(i(t.inputs,!0),r)],u=e[r];return u instanceof Array?u.map(function(t){return n.formatInput(o,[t])}):n.formatInput(o,[u])})},s=function(t,e,n){return function(r,o){var i=o||{};return i.address=t,i.topics=[],i.topics.push(e),r&&(i.topics=i.topics.concat(u(n,r))),i}},c=function(t,e,n){var r=e.slice(),o=n.slice();return t.reduce(function(t,e){var n;return n=e.indexed?r.splice(0,1)[0]:o.splice(0,1)[0],t[e.name]=n,t},{})},l=function(t){return function(e){var o={event:r.extractDisplayName(t.name),number:e.number,hash:e.hash,args:{}};if(e.topics=e.topic,!e.topics)return o;var a=i(t.inputs,!0),u="0x"+e.topics.slice(1,e.topics.length).map(function(t){return t.slice(2)}).join(""),s=n.formatOutput(a,u),l=i(t.inputs,!1),f=n.formatOutput(l,e.data);return o.args=c(t.inputs,s,f),o}},f=function(t,e){for(var n=0;n Date: Sat, 21 Mar 2015 20:48:02 +0100 Subject: [PATCH 22/66] AlethZero now uses .ethereum to store its chain. Fixes #1217. --- alethzero/MainWin.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/alethzero/MainWin.cpp b/alethzero/MainWin.cpp index d99626ff0..dfd439816 100644 --- a/alethzero/MainWin.cpp +++ b/alethzero/MainWin.cpp @@ -162,7 +162,7 @@ Main::Main(QWidget *parent) : QSettings s("ethereum", "alethzero"); m_networkConfig = s.value("peers").toByteArray(); bytesConstRef network((byte*)m_networkConfig.data(), m_networkConfig.size()); - m_webThree.reset(new WebThreeDirect(string("AlethZero/v") + dev::Version + "/" DEV_QUOTED(ETH_BUILD_TYPE) "/" DEV_QUOTED(ETH_BUILD_PLATFORM), getDataDir() + "/AlethZero", false, {"eth", "shh"}, p2p::NetworkPreferences(), network)); + m_webThree.reset(new WebThreeDirect(string("AlethZero/v") + dev::Version + "/" DEV_QUOTED(ETH_BUILD_TYPE) "/" DEV_QUOTED(ETH_BUILD_PLATFORM), getDataDir(), false, {"eth", "shh"}, p2p::NetworkPreferences(), network)); m_httpConnector.reset(new jsonrpc::HttpServer(8080)); m_server.reset(new OurWebThreeStubServer(*m_httpConnector, *web3(), keysAsVector(m_myKeys), this)); From 387e67ee40c73006623481680c6e255d5ccedd60 Mon Sep 17 00:00:00 2001 From: caktux Date: Sat, 21 Mar 2015 15:57:40 -0400 Subject: [PATCH 23/66] apply fix for #1250 to neth, take some creds --- neth/main.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/neth/main.cpp b/neth/main.cpp index 275ac3ea4..80b3bc261 100644 --- a/neth/main.cpp +++ b/neth/main.cpp @@ -65,7 +65,7 @@ bool isFalse(std::string const& _m) void help() { cout - << "Usage neth [OPTIONS] " << endl + << "Usage neth [OPTIONS]" << endl << "Options:" << endl << " -a,--address Set the coinbase (mining payout) address to addr (default: auto)." << endl << " -c,--client-name Add a name to your client's version string (default: blank)." << endl @@ -122,7 +122,7 @@ string credits() std::ostringstream ccout; ccout << "NEthereum (++) " << dev::Version << endl - << " Code by Gav Wood & , (c) 2013, 2014." << endl + << " Code by Gav Wood & caktux, (c) 2013, 2014, 2015." << endl << " Based on a design by Vitalik Buterin." << endl << endl; ccout << "Type 'netstart 30303' to start networking" << endl; @@ -428,7 +428,10 @@ int main(int argc, char** argv) else if (arg == "-V" || arg == "--version") version(); else - remoteHost = argv[i]; + { + cerr << "Invalid argument: " << arg << endl; + exit(-1); + } } if (!clientName.empty()) From bc0100e48e1100f6dfc2d68d9762f7b6d7990991 Mon Sep 17 00:00:00 2001 From: subtly Date: Sun, 22 Mar 2015 02:30:13 +0100 Subject: [PATCH 24/66] Add response timeout to handshake. Update cancel() to prevent race condition. --- libp2p/RLPxHandshake.cpp | 9 ++++++++- libp2p/RLPxHandshake.h | 14 ++++++++++---- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/libp2p/RLPxHandshake.cpp b/libp2p/RLPxHandshake.cpp index b6df5f8e0..fe342a119 100644 --- a/libp2p/RLPxHandshake.cpp +++ b/libp2p/RLPxHandshake.cpp @@ -139,7 +139,7 @@ void RLPXHandshake::error() void RLPXHandshake::transition(boost::system::error_code _ech) { - if (_ech || m_nextState == Error) + if (_ech || m_nextState == Error || m_cancel) return error(); auto self(shared_from_this()); @@ -259,4 +259,11 @@ void RLPXHandshake::transition(boost::system::error_code _ech) } }); } + + m_idleTimer.expires_from_now(c_timeout); + m_idleTimer.async_wait([this, self](boost::system::error_code const& _ec) + { + if (!_ec) + cancel(); + }); } diff --git a/libp2p/RLPxHandshake.h b/libp2p/RLPxHandshake.h index aac8f4b5a..5e51aa4f8 100644 --- a/libp2p/RLPxHandshake.h +++ b/libp2p/RLPxHandshake.h @@ -62,17 +62,18 @@ class RLPXHandshake: public std::enable_shared_from_this public: /// Setup incoming connection. - RLPXHandshake(Host* _host, std::shared_ptr const& _socket): m_host(_host), m_originated(false), m_socket(_socket) { crypto::Nonce::get().ref().copyTo(m_nonce.ref()); } + RLPXHandshake(Host* _host, std::shared_ptr const& _socket): m_host(_host), m_originated(false), m_socket(_socket), m_idleTimer(m_socket->ref().get_io_service()) { crypto::Nonce::get().ref().copyTo(m_nonce.ref()); } /// Setup outbound connection. - RLPXHandshake(Host* _host, std::shared_ptr const& _socket, NodeId _remote): m_host(_host), m_remote(_remote), m_originated(true), m_socket(_socket) { crypto::Nonce::get().ref().copyTo(m_nonce.ref()); } + RLPXHandshake(Host* _host, std::shared_ptr const& _socket, NodeId _remote): m_host(_host), m_remote(_remote), m_originated(true), m_socket(_socket), m_idleTimer(m_socket->ref().get_io_service()) { crypto::Nonce::get().ref().copyTo(m_nonce.ref()); } ~RLPXHandshake() {} /// Start handshake. void start() { transition(); } - void cancel() { m_nextState = Error; } + /// Cancels handshake preventing + void cancel() { m_cancel = true; } protected: /// Write Auth message to socket and transitions to AckAuth. @@ -93,7 +94,11 @@ protected: /// Performs transition for m_nextState. void transition(boost::system::error_code _ech = boost::system::error_code()); + /// Timeout for remote to respond to transition events. Enforced by m_idleTimer and refreshed by transition(). + boost::posix_time::milliseconds const c_timeout = boost::posix_time::milliseconds(1000); + State m_nextState = New; ///< Current or expected state of transition. + bool m_cancel = false; ///< Will be set to true if connection was canceled. Host* m_host; ///< Host which provides m_alias, protocolVersion(), m_clientVersion, caps(), and TCP listenPort(). @@ -119,7 +124,8 @@ protected: /// Passed onto Host which will take ownership. RLPXFrameIO* m_io = nullptr; - std::shared_ptr m_socket; ///< Socket. + std::shared_ptr m_socket; ///< Socket. + boost::asio::deadline_timer m_idleTimer; ///< Timer which enforces c_timeout. }; } From 14568fc8392e2fd253f0efae3784b2ea9ef62cc4 Mon Sep 17 00:00:00 2001 From: subtly Date: Sun, 22 Mar 2015 02:41:55 +0100 Subject: [PATCH 25/66] logging for handshake timeout --- libp2p/RLPxHandshake.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libp2p/RLPxHandshake.cpp b/libp2p/RLPxHandshake.cpp index fe342a119..4d8f2417f 100644 --- a/libp2p/RLPxHandshake.cpp +++ b/libp2p/RLPxHandshake.cpp @@ -264,6 +264,9 @@ void RLPXHandshake::transition(boost::system::error_code _ech) m_idleTimer.async_wait([this, self](boost::system::error_code const& _ec) { if (!_ec) + { + clog(NetWarn) << "Disconnecting " << m_socket->remoteEndpoint() << " (Handshake Timeout)"; cancel(); + } }); } From 360e2a32bc001803dddb4f607d1133a8b1c465fd Mon Sep 17 00:00:00 2001 From: subtly Date: Sun, 22 Mar 2015 13:59:47 +0100 Subject: [PATCH 26/66] update version number for save/restore of nodeTable --- libp2p/Host.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libp2p/Host.cpp b/libp2p/Host.cpp index 78a8232fd..082ff6a2f 100644 --- a/libp2p/Host.cpp +++ b/libp2p/Host.cpp @@ -708,7 +708,7 @@ bytes Host::saveNetwork() const } RLPStream ret(3); - ret << 1 << m_alias.secret(); + ret << 2 << m_alias.secret(); ret.appendList(count).appendRaw(network.out(), count); return ret.out(); } @@ -721,7 +721,7 @@ void Host::restoreNetwork(bytesConstRef _b) RecursiveGuard l(x_sessions); RLP r(_b); - if (r.itemCount() > 0 && r[0].isInt() && r[0].toInt() == 1) + if (r.itemCount() > 0 && r[0].isInt() && r[0].toInt() == 2) { // r[0] = version // r[1] = key From 11c1b13e272eb21be3825009ae331a0ddda6d21a Mon Sep 17 00:00:00 2001 From: subtly Date: Sun, 22 Mar 2015 17:12:14 +0100 Subject: [PATCH 27/66] clarify peersAdded log. Increment failedAttempts so fallback timer goes up. Temporarily exclude private addresses from network-restore. This exclusion will be removed when unit tests are written for local/private/public/failed-pnp scenarios. --- libp2p/Host.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/libp2p/Host.cpp b/libp2p/Host.cpp index 082ff6a2f..8226c35fb 100644 --- a/libp2p/Host.cpp +++ b/libp2p/Host.cpp @@ -260,7 +260,7 @@ void Host::onNodeTableEvent(NodeId const& _n, NodeTableEventType const& _e) p->required = n.required; m_peers[_n] = p; - clog(NetNote) << "p2p.host.peers.events.peersAdded " << _n << p->endpoint.tcp.address() << p->endpoint.udp.address(); + clog(NetNote) << "p2p.host.peers.events.peersAdded " << _n << "udp:" << p->endpoint.udp.address() << "tcp:" << p->endpoint.tcp.address(); } p->endpoint.tcp = n.endpoint.tcp; } @@ -474,6 +474,7 @@ void Host::connect(std::shared_ptr const& _p) clog(NetConnect) << "Connection refused to node" << _p->id.abridged() << "@" << _p->peerEndpoint() << "(" << ec.message() << ")"; _p->m_lastDisconnect = TCPError; _p->m_lastAttempted = std::chrono::system_clock::now(); + _p->m_failedAttempts++; } else { @@ -741,6 +742,13 @@ void Host::restoreNetwork(bytesConstRef _b) tcp = bi::tcp::endpoint(bi::address_v6(i[0].toArray()), i[1].toInt()); udp = bi::udp::endpoint(bi::address_v6(i[0].toArray()), i[1].toInt()); } + + // skip private addresses + // todo: to support private addresseses entries must be stored + // and managed externally by host rather than nodetable. + if (isPrivateAddress(tcp.address()) || isPrivateAddress(udp.address())) + continue; + auto id = (NodeId)i[2]; if (i.itemCount() == 3) m_nodeTable->addNode(id, udp, tcp); From b8f49b09292edccee50ed85feb8235ce2b54f463 Mon Sep 17 00:00:00 2001 From: subtly Date: Sun, 22 Mar 2015 17:41:35 +0100 Subject: [PATCH 28/66] Ignore 0.0.0.0 addresses. --- libp2p/NodeTable.cpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/libp2p/NodeTable.cpp b/libp2p/NodeTable.cpp index 0f51b29cf..a54f4acdd 100644 --- a/libp2p/NodeTable.cpp +++ b/libp2p/NodeTable.cpp @@ -70,6 +70,20 @@ shared_ptr NodeTable::addNode(Public const& _pubk, bi::udp::endpoint shared_ptr NodeTable::addNode(Node const& _node) { + if (_node.endpoint.udp.address().to_string() == "0.0.0.0" || _node.endpoint.tcp.address().to_string() == "0.0.0.0") + { + string ptype; + if (_node.endpoint.udp.address().to_string() != "0.0.0.0") + ptype = "TCP"; + else if (_node.endpoint.tcp.address().to_string() != "0.0.0.0") + ptype = "UDP"; + else + ptype = "TCP,UDP"; + + clog(NodeTableWarn) << "addNode Failed. Invalid" << ptype << "address 0.0.0.0 for" << _node.id.abridged(); + return move(shared_ptr()); + } + // ping address if nodeid is empty if (!_node.id) { From 3e2572e6a2a81409f88deaa82082d6adf61814e7 Mon Sep 17 00:00:00 2001 From: subtly Date: Sun, 22 Mar 2015 18:33:15 +0100 Subject: [PATCH 29/66] constant for discovery protocol version --- libp2p/Host.cpp | 4 ++-- libp2p/NodeTable.cpp | 2 +- libp2p/NodeTable.h | 4 ++++ test/peer.cpp | 2 +- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/libp2p/Host.cpp b/libp2p/Host.cpp index 8226c35fb..efa42cc17 100644 --- a/libp2p/Host.cpp +++ b/libp2p/Host.cpp @@ -709,7 +709,7 @@ bytes Host::saveNetwork() const } RLPStream ret(3); - ret << 2 << m_alias.secret(); + ret << NodeTable::s_version << m_alias.secret(); ret.appendList(count).appendRaw(network.out(), count); return ret.out(); } @@ -722,7 +722,7 @@ void Host::restoreNetwork(bytesConstRef _b) RecursiveGuard l(x_sessions); RLP r(_b); - if (r.itemCount() > 0 && r[0].isInt() && r[0].toInt() == 2) + if (r.itemCount() > 0 && r[0].isInt() && r[0].toInt() == NodeTable::s_version) { // r[0] = version // r[1] = key diff --git a/libp2p/NodeTable.cpp b/libp2p/NodeTable.cpp index a54f4acdd..288e89797 100644 --- a/libp2p/NodeTable.cpp +++ b/libp2p/NodeTable.cpp @@ -477,7 +477,7 @@ void NodeTable::onReceived(UDPSocketFace*, bi::udp::endpoint const& _from, bytes case PingNode::type: { PingNode in = PingNode::fromBytesConstRef(_from, rlpBytes); - if (in.version != 0x2) + if (in.version != s_version) { if (auto n = nodeEntry(nodeid)) dropNode(n); diff --git a/libp2p/NodeTable.h b/libp2p/NodeTable.h index fbeb53a2d..130f325ae 100644 --- a/libp2p/NodeTable.h +++ b/libp2p/NodeTable.h @@ -135,6 +135,10 @@ class NodeTable: UDPSocketEvents, public std::enable_shared_from_this using EvictionTimeout = std::pair, NodeId>; ///< First NodeId may be evicted and replaced with second NodeId. public: + /// Version of Discovery protocol + static unsigned const s_version = 2; + + /// Constructor requiring host for I/O, credentials, and IP Address,port to listen on. NodeTable(ba::io_service& _io, KeyPair _alias, uint16_t _udpPort = 30303); ~NodeTable(); diff --git a/test/peer.cpp b/test/peer.cpp index 14712d4f1..4732d319b 100644 --- a/test/peer.cpp +++ b/test/peer.cpp @@ -90,7 +90,7 @@ BOOST_AUTO_TEST_CASE(save_nodes) RLP r(firstHostNetwork); BOOST_REQUIRE(r.itemCount() == 3); - BOOST_REQUIRE(r[0].toInt() == 1); + BOOST_REQUIRE(r[0].toInt() == NodeTable::s_version); BOOST_REQUIRE_EQUAL(r[1].toBytes().size(), 32); // secret BOOST_REQUIRE_EQUAL(r[2].itemCount(), 5); } From 8cc7fb94ba3396fd169324d2d7588637cf93d6f9 Mon Sep 17 00:00:00 2001 From: subtly Date: Sun, 22 Mar 2015 18:35:34 +0100 Subject: [PATCH 30/66] codingstandards --- libp2p/Host.cpp | 4 ++-- libp2p/NodeTable.cpp | 2 +- libp2p/NodeTable.h | 2 +- test/peer.cpp | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/libp2p/Host.cpp b/libp2p/Host.cpp index efa42cc17..de4c19c2d 100644 --- a/libp2p/Host.cpp +++ b/libp2p/Host.cpp @@ -709,7 +709,7 @@ bytes Host::saveNetwork() const } RLPStream ret(3); - ret << NodeTable::s_version << m_alias.secret(); + ret << NodeTable::c_version << m_alias.secret(); ret.appendList(count).appendRaw(network.out(), count); return ret.out(); } @@ -722,7 +722,7 @@ void Host::restoreNetwork(bytesConstRef _b) RecursiveGuard l(x_sessions); RLP r(_b); - if (r.itemCount() > 0 && r[0].isInt() && r[0].toInt() == NodeTable::s_version) + if (r.itemCount() > 0 && r[0].isInt() && r[0].toInt() == NodeTable::c_version) { // r[0] = version // r[1] = key diff --git a/libp2p/NodeTable.cpp b/libp2p/NodeTable.cpp index 288e89797..a79eae12a 100644 --- a/libp2p/NodeTable.cpp +++ b/libp2p/NodeTable.cpp @@ -477,7 +477,7 @@ void NodeTable::onReceived(UDPSocketFace*, bi::udp::endpoint const& _from, bytes case PingNode::type: { PingNode in = PingNode::fromBytesConstRef(_from, rlpBytes); - if (in.version != s_version) + if (in.version != c_version) { if (auto n = nodeEntry(nodeid)) dropNode(n); diff --git a/libp2p/NodeTable.h b/libp2p/NodeTable.h index 130f325ae..4c2e52bd6 100644 --- a/libp2p/NodeTable.h +++ b/libp2p/NodeTable.h @@ -136,7 +136,7 @@ class NodeTable: UDPSocketEvents, public std::enable_shared_from_this public: /// Version of Discovery protocol - static unsigned const s_version = 2; + static unsigned const c_version = 2; /// Constructor requiring host for I/O, credentials, and IP Address,port to listen on. NodeTable(ba::io_service& _io, KeyPair _alias, uint16_t _udpPort = 30303); diff --git a/test/peer.cpp b/test/peer.cpp index 4732d319b..9a68401e0 100644 --- a/test/peer.cpp +++ b/test/peer.cpp @@ -90,7 +90,7 @@ BOOST_AUTO_TEST_CASE(save_nodes) RLP r(firstHostNetwork); BOOST_REQUIRE(r.itemCount() == 3); - BOOST_REQUIRE(r[0].toInt() == NodeTable::s_version); + BOOST_REQUIRE(r[0].toInt() == NodeTable::c_version); BOOST_REQUIRE_EQUAL(r[1].toBytes().size(), 32); // secret BOOST_REQUIRE_EQUAL(r[2].itemCount(), 5); } From ee7608fe603eea574c06cc90236df4089ae8d9ea Mon Sep 17 00:00:00 2001 From: subtly Date: Sun, 22 Mar 2015 18:39:56 +0100 Subject: [PATCH 31/66] NodeTable constructor requires and listens to explicit IP address instead of defaulting to 0.0.0.0 (all addresses). --- libp2p/Host.cpp | 5 ++--- libp2p/NodeTable.cpp | 6 +++--- libp2p/NodeTable.h | 4 ++-- libp2p/UDP.h | 4 ++++ test/net.cpp | 6 +++--- test/peer.cpp | 6 +++--- 6 files changed, 17 insertions(+), 14 deletions(-) diff --git a/libp2p/Host.cpp b/libp2p/Host.cpp index de4c19c2d..09c4db633 100644 --- a/libp2p/Host.cpp +++ b/libp2p/Host.cpp @@ -610,8 +610,7 @@ void Host::startedWorking() else clog(NetNote) << "p2p.start.notice id:" << id().abridged() << "Listen port is invalid or unavailable. Node Table using default port (30303)."; - // TODO: add m_tcpPublic endpoint; sort out endpoint stuff for nodetable - m_nodeTable.reset(new NodeTable(m_ioService, m_alias, m_listenPort > 0 ? m_listenPort : 30303)); + m_nodeTable.reset(new NodeTable(m_ioService, m_alias, bi::address::from_string(listenAddress()), listenPort() > 0 ? listenPort() : 30303)); m_nodeTable->setEventHandler(new HostNodeTableHandler(*this)); restoreNetwork(&m_restoreNetwork); @@ -675,7 +674,7 @@ bytes Host::saveNetwork() const // TODO: alpha: Figure out why it ever shares these ports.//p.address.port() >= 30300 && p.address.port() <= 30305 && // TODO: alpha: if/how to save private addresses // Only save peers which have connected within 2 days, with properly-advertised port and public IP address - if (chrono::system_clock::now() - p.m_lastConnected < chrono::seconds(3600 * 48) && p.peerEndpoint().port() > 0 && p.peerEndpoint().port() < /*49152*/32768 && p.id != id() && !isPrivateAddress(p.peerEndpoint().address())) + if (chrono::system_clock::now() - p.m_lastConnected < chrono::seconds(3600 * 48) && p.peerEndpoint().port() > 0 && p.peerEndpoint().port() < /*49152*/32768 && p.id != id() && !isPrivateAddress(p.endpoint.udp.address()) && !isPrivateAddress(p.endpoint.tcp.address())) { network.appendList(10); if (p.peerEndpoint().address().is_v4()) diff --git a/libp2p/NodeTable.cpp b/libp2p/NodeTable.cpp index a79eae12a..4710c5471 100644 --- a/libp2p/NodeTable.cpp +++ b/libp2p/NodeTable.cpp @@ -27,11 +27,11 @@ using namespace dev::p2p; NodeEntry::NodeEntry(Node _src, Public _pubk, NodeIPEndpoint _gw): Node(_pubk, _gw), distance(NodeTable::distance(_src.id,_pubk)) {} NodeEntry::NodeEntry(Node _src, Public _pubk, bi::udp::endpoint _udp): Node(_pubk, NodeIPEndpoint(_udp)), distance(NodeTable::distance(_src.id,_pubk)) {} -NodeTable::NodeTable(ba::io_service& _io, KeyPair _alias, uint16_t _udp): - m_node(Node(_alias.pub(), bi::udp::endpoint())), +NodeTable::NodeTable(ba::io_service& _io, KeyPair _alias, bi::address const& _udpAddress, uint16_t _udp): + m_node(Node(_alias.pub(), bi::udp::endpoint(_udpAddress, _udp))), m_secret(_alias.sec()), m_io(_io), - m_socket(new NodeSocket(m_io, *this, _udp)), + m_socket(new NodeSocket(m_io, *this, m_node.endpoint.udp)), m_socketPointer(m_socket.get()), m_bucketRefreshTimer(m_io), m_evictionCheckTimer(m_io) diff --git a/libp2p/NodeTable.h b/libp2p/NodeTable.h index 4c2e52bd6..49be27045 100644 --- a/libp2p/NodeTable.h +++ b/libp2p/NodeTable.h @@ -138,8 +138,8 @@ public: /// Version of Discovery protocol static unsigned const c_version = 2; - /// Constructor requiring host for I/O, credentials, and IP Address,port to listen on. - NodeTable(ba::io_service& _io, KeyPair _alias, uint16_t _udpPort = 30303); + /// Constructor requiring host for I/O, credentials, and IP Address and port to listen on. + NodeTable(ba::io_service& _io, KeyPair _alias, bi::address const& _udpAddress, uint16_t _udpPort = 30303); ~NodeTable(); /// Returns distance based on xor metric two node ids. Used by NodeEntry and NodeTable. diff --git a/libp2p/UDP.h b/libp2p/UDP.h index 3c3399acb..091f3cc2a 100644 --- a/libp2p/UDP.h +++ b/libp2p/UDP.h @@ -113,6 +113,10 @@ public: enum { maxDatagramSize = MaxDatagramSize }; static_assert(maxDatagramSize < 65507, "UDP datagrams cannot be larger than 65507 bytes"); + /// Create socket for specific endpoint. + UDPSocket(ba::io_service& _io, UDPSocketEvents& _host, bi::udp::endpoint _endpoint): m_host(_host), m_endpoint(_endpoint), m_socket(_io) { m_started.store(false); m_closed.store(true); }; + + /// Create socket which listens to all ports. UDPSocket(ba::io_service& _io, UDPSocketEvents& _host, unsigned _port): m_host(_host), m_endpoint(bi::udp::v4(), _port), m_socket(_io) { m_started.store(false); m_closed.store(true); }; virtual ~UDPSocket() { disconnect(); } diff --git a/test/net.cpp b/test/net.cpp index 3a69a627b..e5cca9b66 100644 --- a/test/net.cpp +++ b/test/net.cpp @@ -53,7 +53,7 @@ protected: struct TestNodeTable: public NodeTable { /// Constructor - TestNodeTable(ba::io_service& _io, KeyPair _alias, uint16_t _port = 30300): NodeTable(_io, _alias, _port) {} + TestNodeTable(ba::io_service& _io, KeyPair _alias, bi::address const& _addr, uint16_t _port = 30300): NodeTable(_io, _alias, _addr, _port) {} static std::vector> createTestNodes(unsigned _count) { @@ -106,10 +106,10 @@ struct TestNodeTable: public NodeTable */ struct TestNodeTableHost: public TestHost { - TestNodeTableHost(unsigned _count = 8): m_alias(KeyPair::create()), nodeTable(new TestNodeTable(m_io, m_alias)), testNodes(TestNodeTable::createTestNodes(_count)) {}; + TestNodeTableHost(unsigned _count = 8): m_alias(KeyPair::create()), nodeTable(new TestNodeTable(m_io, m_alias, bi::address::from_string("127.0.0.1"))), testNodes(TestNodeTable::createTestNodes(_count)) {}; ~TestNodeTableHost() { m_io.stop(); stopWorking(); } - void setup() { for (auto n: testNodes) nodeTables.push_back(make_shared(m_io,n.first,n.second)); } + void setup() { for (auto n: testNodes) nodeTables.push_back(make_shared(m_io,n.first, bi::address::from_string("127.0.0.1"),n.second)); } void pingAll() { for (auto& t: nodeTables) t->pingTestNodes(testNodes); } diff --git a/test/peer.cpp b/test/peer.cpp index 9a68401e0..3ad2e2946 100644 --- a/test/peer.cpp +++ b/test/peer.cpp @@ -35,8 +35,8 @@ BOOST_AUTO_TEST_CASE(host) auto oldLogVerbosity = g_logVerbosity; g_logVerbosity = 10; - NetworkPreferences host1prefs(30301, "127.0.0.1", true, true); - NetworkPreferences host2prefs(30302, "127.0.0.1", true, true); + NetworkPreferences host1prefs(30301, "127.0.0.1", false, true); + NetworkPreferences host2prefs(30302, "127.0.0.1", false, true); Host host1("Test", host1prefs); host1.start(); @@ -62,7 +62,7 @@ BOOST_AUTO_TEST_CASE(save_nodes) std::list hosts; for (auto i:{0,1,2,3,4,5}) { - Host* h = new Host("Test", NetworkPreferences(30300 + i, "127.0.0.1", true, true)); + Host* h = new Host("Test", NetworkPreferences(30300 + i, "127.0.0.1", false, true)); h->setIdealPeerCount(10); // starting host is required so listenport is available h->start(); From 65de6aaa4d1b3ed7c702f4cfb260c187bd1ced8a Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Sun, 22 Mar 2015 18:56:07 +0100 Subject: [PATCH 32/66] Diagnostics and API cleanup. --- libethereum/EthereumPeer.cpp | 1 + libp2p/Host.cpp | 6 ++++++ libp2p/Host.h | 6 ------ libp2p/Session.cpp | 1 + 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/libethereum/EthereumPeer.cpp b/libethereum/EthereumPeer.cpp index a6211505f..f318a1757 100644 --- a/libethereum/EthereumPeer.cpp +++ b/libethereum/EthereumPeer.cpp @@ -48,6 +48,7 @@ EthereumPeer::EthereumPeer(Session* _s, HostCapabilityFace* _h, unsigned _i): EthereumPeer::~EthereumPeer() { + clogS(NetMessageSummary) << "Aborting Sync :-("; abortSync(); } diff --git a/libp2p/Host.cpp b/libp2p/Host.cpp index 78a8232fd..789418893 100644 --- a/libp2p/Host.cpp +++ b/libp2p/Host.cpp @@ -42,6 +42,12 @@ using namespace std; using namespace dev; using namespace dev::p2p; +/// Interval at which Host::run will call keepAlivePeers to ping peers. +std::chrono::seconds const c_keepAliveInterval = std::chrono::seconds(30); + +/// Disconnect timeout after failure to respond to keepAlivePeers ping. +std::chrono::milliseconds const c_keepAliveTimeOut = std::chrono::milliseconds(1000); + HostNodeTableHandler::HostNodeTableHandler(Host& _host): m_host(_host) {} void HostNodeTableHandler::processEvent(NodeId const& _n, NodeTableEventType const& _e) diff --git a/libp2p/Host.h b/libp2p/Host.h index ff27807a7..50abad2af 100644 --- a/libp2p/Host.h +++ b/libp2p/Host.h @@ -94,12 +94,6 @@ public: /// Will block on network process events. virtual ~Host(); - /// Interval at which Host::run will call keepAlivePeers to ping peers. - std::chrono::seconds const c_keepAliveInterval = std::chrono::seconds(30); - - /// Disconnect timeout after failure to respond to keepAlivePeers ping. - std::chrono::milliseconds const c_keepAliveTimeOut = std::chrono::milliseconds(1000); - /// Default host for current version of client. static std::string pocHost(); diff --git a/libp2p/Session.cpp b/libp2p/Session.cpp index 2c6530a2d..d7bfca34e 100644 --- a/libp2p/Session.cpp +++ b/libp2p/Session.cpp @@ -51,6 +51,7 @@ Session::Session(Host* _s, RLPXFrameIO* _io, std::shared_ptr const& _n, Pe Session::~Session() { + clogS(NetMessageSummary) << "Closing Peer Session :-("; m_peer->m_lastConnected = m_peer->m_lastAttempted - chrono::seconds(1); // Read-chain finished for one reason or another. From 14c2e4cab856ec67f8385787fe05de1b5e58fab9 Mon Sep 17 00:00:00 2001 From: subtly Date: Sun, 22 Mar 2015 19:05:39 +0100 Subject: [PATCH 33/66] fix net/ unit tests for nodetable updates --- libp2p/NodeTable.cpp | 4 ++-- test/net.cpp | 9 +++++++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/libp2p/NodeTable.cpp b/libp2p/NodeTable.cpp index 4710c5471..7cac14938 100644 --- a/libp2p/NodeTable.cpp +++ b/libp2p/NodeTable.cpp @@ -340,7 +340,7 @@ void NodeTable::noteActiveNode(Public const& _pubk, bi::udp::endpoint const& _en s.nodes.push_back(node); s.touch(); - if (!removed) + if (!removed && m_nodeEventHandler) m_nodeEventHandler->appendEvent(node->id, NodeEntryAdded); } } @@ -349,7 +349,7 @@ void NodeTable::noteActiveNode(Public const& _pubk, bi::udp::endpoint const& _en s.nodes.push_back(node); s.touch(); - if (!removed) + if (!removed && m_nodeEventHandler) m_nodeEventHandler->appendEvent(node->id, NodeEntryAdded); } } diff --git a/test/net.cpp b/test/net.cpp index e5cca9b66..23ad0fb4a 100644 --- a/test/net.cpp +++ b/test/net.cpp @@ -89,7 +89,16 @@ struct TestNodeTable: public NodeTable bi::address ourIp = bi::address::from_string("127.0.0.1"); for (auto& n: _testNodes) if (_count--) + { + // manually add node for test + { + Guard ln(x_nodes); + shared_ptr node(new NodeEntry(m_node, n.first.pub(), NodeIPEndpoint(bi::udp::endpoint(ourIp, n.second), bi::tcp::endpoint(ourIp, n.second)))); + node->pending = false; + m_nodes[node->id] = node; + } noteActiveNode(n.first.pub(), bi::udp::endpoint(ourIp, n.second)); + } else break; } From b78634637bc78d877120041d7b38a2aa9c357af9 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Sun, 22 Mar 2015 19:40:04 +0100 Subject: [PATCH 34/66] Transact now prevents executing failing transactions. --- alethzero/Transact.cpp | 45 ++++++++++++++++++++++++------------------ alethzero/Transact.h | 1 + 2 files changed, 27 insertions(+), 19 deletions(-) diff --git a/alethzero/Transact.cpp b/alethzero/Transact.cpp index 35a9c47d2..c9cd5e7b4 100644 --- a/alethzero/Transact.cpp +++ b/alethzero/Transact.cpp @@ -186,6 +186,7 @@ void Transact::rejigData() { if (!ethereum()) return; + m_allGood = true; if (isCreation()) { string src = ui->data->toPlainText().toStdString(); @@ -210,11 +211,11 @@ void Transact::rejigData() { ostringstream error; solidity::SourceReferenceFormatter::printExceptionInformation(error, exception, "Error", compiler); - solidity = "

Solidity

" + QString::fromStdString(error.str()).toHtmlEscaped() + "
"; + errors.push_back("Solidity: " + error.str()); } catch (...) { - solidity = "

Solidity

Uncaught exception.
"; + errors.push_back("Solidity: Uncaught exception"); } } #ifndef _MSC_VER @@ -223,8 +224,6 @@ void Transact::rejigData() try { m_data = dev::asBytes(::compile(src)); - for (auto& i: errors) - i = "(LLL " + i + ")"; } catch (string const& err) { @@ -237,22 +236,18 @@ void Transact::rejigData() m_data = compileLLL(src, ui->optimize->isChecked(), &errors); if (errors.empty()) { - auto asmcode = compileLLLToAsm(src, false); - lll = "

Pre

" + QString::fromStdString(asmcode).toHtmlEscaped() + "
"; - if (ui->optimize->isChecked()) - { - asmcode = compileLLLToAsm(src, true); - lll = "

Opt

" + QString::fromStdString(asmcode).toHtmlEscaped() + "
" + lll; - } + auto asmcode = compileLLLToAsm(src, ui->optimize->isChecked()); + lll = "

LLL

" + QString::fromStdString(asmcode).toHtmlEscaped() + "
"; } } - QString errs; + QString htmlErrors; qint64 gasNeeded = 0; if (errors.size()) { - errs = "

Errors

"; + htmlErrors = "

Errors

"; for (auto const& i: errors) - errs.append("
" + QString::fromStdString(i).toHtmlEscaped() + "
"); + htmlErrors.append("
" + QString::fromStdString(i).toHtmlEscaped() + "
"); + m_allGood = false; } else { @@ -260,26 +255,32 @@ void Transact::rejigData() { auto s = findSecret(value() + ethereum()->gasLimitRemaining() * gasPrice()); if (!s) - errs += "
ERROR No single account contains enough gas.
"; + htmlErrors += "
WARNING No single account contains a comfortable amount of gas.
"; // TODO: use account with most balance anyway. else { ExecutionResult er = ethereum()->create(s, value(), m_data, ethereum()->gasLimitRemaining(), gasPrice()); gasNeeded = (qint64)er.gasUsed; auto base = (qint64)Interface::txGas(m_data, 0); - errs += QString("
INFO Gas required: %1 base, %2 init
").arg(base).arg((qint64)er.gasUsed - base); + htmlErrors += QString("
INFO Gas required: %1 base, %2 init
").arg(base).arg((qint64)er.gasUsed - base); if (er.excepted != TransactionException::None) - errs += "
ERROR " + QString::fromStdString(toString(er.excepted)) + "
"; + { + htmlErrors += "
ERROR " + QString::fromStdString(toString(er.excepted)) + "
"; + m_allGood = false; + } if (er.codeDeposit == CodeDeposit::Failed) - errs += "
ERROR Code deposit failed due to insufficient gas
"; + { + htmlErrors += "
ERROR Code deposit failed due to insufficient gas
"; + m_allGood = false; + } } } else gasNeeded = (qint64)Interface::txGas(m_data, 0); } - ui->code->setHtml(errs + lll + solidity + "

Code

" + QString::fromStdString(disassemble(m_data)).toHtmlEscaped() + "

Hex

" Div(Mono) + QString::fromStdString(toHex(m_data)) + ""); + ui->code->setHtml(htmlErrors + lll + solidity + "

Code

" + QString::fromStdString(disassemble(m_data)).toHtmlEscaped() + "

Hex

" Div(Mono) + QString::fromStdString(toHex(m_data)) + ""); if (ui->gas->value() == ui->gas->minimum()) { @@ -296,6 +297,7 @@ void Transact::rejigData() } else { + m_allGood = true; auto base = (qint64)Interface::txGas(m_data, 0); m_data = parseData(ui->data->toPlainText().toStdString()); auto to = m_context->fromString(ui->destination->currentText()); @@ -326,7 +328,10 @@ void Transact::rejigData() errs += QString("
INFO Gas required: %1 base, %2 exec
").arg(base).arg((qint64)er.gasUsed - base); if (er.excepted != TransactionException::None) + { errs += "
ERROR " + QString::fromStdString(toString(er.excepted)) + "
"; + m_allGood = false; + } } } else @@ -356,6 +361,8 @@ void Transact::rejigData() ui->code->setHtml(errs + "

NatSpec

" + natspec + "

Dump

" + QString::fromStdString(dev::memDump(m_data, 8, true)) + "

Hex

" + Div(Mono) + QString::fromStdString(toHex(m_data)) + ""); } updateFee(); + + ui->send->setEnabled(m_allGood); } Secret Transact::findSecret(u256 _totalReq) const diff --git a/alethzero/Transact.h b/alethzero/Transact.h index b3702a6ae..0ad9d5653 100644 --- a/alethzero/Transact.h +++ b/alethzero/Transact.h @@ -80,4 +80,5 @@ private: dev::eth::Client* m_ethereum = nullptr; Context* m_context = nullptr; NatSpecFace* m_natSpecDB = nullptr; + bool m_allGood = false; }; From 7445f9020efeac740b99c9656c7cbf5fd540dbbf Mon Sep 17 00:00:00 2001 From: subtly Date: Sun, 22 Mar 2015 20:08:32 +0100 Subject: [PATCH 35/66] Merge host and nodetable network protocol version. --- libp2p/Common.cpp | 2 ++ libp2p/Common.h | 3 +++ libp2p/Host.cpp | 11 +++-------- libp2p/Host.h | 3 --- libp2p/NodeTable.cpp | 2 +- libp2p/NodeTable.h | 5 +---- libp2p/RLPxHandshake.cpp | 2 +- test/peer.cpp | 2 +- 8 files changed, 12 insertions(+), 18 deletions(-) diff --git a/libp2p/Common.cpp b/libp2p/Common.cpp index e0f3b5629..0429c52ab 100644 --- a/libp2p/Common.cpp +++ b/libp2p/Common.cpp @@ -24,6 +24,8 @@ using namespace std; using namespace dev; using namespace dev::p2p; +const unsigned dev::p2p::c_protocolVersion = 3; + // Helper function to determine if an address falls within one of the reserved ranges // For V4: // Class A "10.*", Class B "172.[16->31].*", Class C "192.168.*" diff --git a/libp2p/Common.h b/libp2p/Common.h index ddf5f78b8..66b3f08e8 100644 --- a/libp2p/Common.h +++ b/libp2p/Common.h @@ -48,6 +48,9 @@ class RLPStream; namespace p2p { +/// Peer network protocol version. +extern const unsigned c_protocolVersion; + using NodeId = h512; bool isPrivateAddress(bi::address const& _addressToCheck); diff --git a/libp2p/Host.cpp b/libp2p/Host.cpp index 4f8ce7981..30cadb515 100644 --- a/libp2p/Host.cpp +++ b/libp2p/Host.cpp @@ -176,11 +176,6 @@ void Host::doneWorking() m_sessions.clear(); } -unsigned Host::protocolVersion() const -{ - return 3; -} - void Host::startPeerSession(Public const& _id, RLP const& _rlp, RLPXFrameIO* _io, bi::tcp::endpoint _endpoint) { shared_ptr p; @@ -211,7 +206,7 @@ void Host::startPeerSession(Public const& _id, RLP const& _rlp, RLPXFrameIO* _io // create session so disconnects are managed auto ps = make_shared(this, _io, p, PeerSessionInfo({_id, clientVersion, _endpoint.address().to_string(), listenPort, chrono::steady_clock::duration(), _rlp[2].toSet(), 0, map()})); - if (protocolVersion != this->protocolVersion()) + if (protocolVersion != dev::p2p::c_protocolVersion) { ps->disconnect(IncompatibleProtocol); return; @@ -714,7 +709,7 @@ bytes Host::saveNetwork() const } RLPStream ret(3); - ret << NodeTable::c_version << m_alias.secret(); + ret << c_protocolVersion << m_alias.secret(); ret.appendList(count).appendRaw(network.out(), count); return ret.out(); } @@ -727,7 +722,7 @@ void Host::restoreNetwork(bytesConstRef _b) RecursiveGuard l(x_sessions); RLP r(_b); - if (r.itemCount() > 0 && r[0].isInt() && r[0].toInt() == NodeTable::c_version) + if (r.itemCount() > 0 && r[0].isInt() && r[0].toInt() == c_protocolVersion) { // r[0] = version // r[1] = key diff --git a/libp2p/Host.h b/libp2p/Host.h index 50abad2af..0feda364f 100644 --- a/libp2p/Host.h +++ b/libp2p/Host.h @@ -97,9 +97,6 @@ public: /// Default host for current version of client. static std::string pocHost(); - /// Basic peer network protocol version. - unsigned protocolVersion() const; - /// Register a peer-capability; all new peer connections will have this capability. template std::shared_ptr registerCapability(T* _t) { _t->m_host = this; auto ret = std::shared_ptr(_t); m_capabilities[std::make_pair(T::staticName(), T::staticVersion())] = ret; return ret; } diff --git a/libp2p/NodeTable.cpp b/libp2p/NodeTable.cpp index 7cac14938..1f024a911 100644 --- a/libp2p/NodeTable.cpp +++ b/libp2p/NodeTable.cpp @@ -477,7 +477,7 @@ void NodeTable::onReceived(UDPSocketFace*, bi::udp::endpoint const& _from, bytes case PingNode::type: { PingNode in = PingNode::fromBytesConstRef(_from, rlpBytes); - if (in.version != c_version) + if (in.version != c_protocolVersion) { if (auto n = nodeEntry(nodeid)) dropNode(n); diff --git a/libp2p/NodeTable.h b/libp2p/NodeTable.h index 49be27045..10ba232c3 100644 --- a/libp2p/NodeTable.h +++ b/libp2p/NodeTable.h @@ -135,9 +135,6 @@ class NodeTable: UDPSocketEvents, public std::enable_shared_from_this using EvictionTimeout = std::pair, NodeId>; ///< First NodeId may be evicted and replaced with second NodeId. public: - /// Version of Discovery protocol - static unsigned const c_version = 2; - /// Constructor requiring host for I/O, credentials, and IP Address and port to listen on. NodeTable(ba::io_service& _io, KeyPair _alias, bi::address const& _udpAddress, uint16_t _udpPort = 30303); ~NodeTable(); @@ -319,7 +316,7 @@ struct PingNode: RLPXDatagram static const uint8_t type = 1; - unsigned version = 2; + unsigned version = c_protocolVersion; std::string ipAddress; unsigned port; unsigned expiration; diff --git a/libp2p/RLPxHandshake.cpp b/libp2p/RLPxHandshake.cpp index 4d8f2417f..1e42995ee 100644 --- a/libp2p/RLPxHandshake.cpp +++ b/libp2p/RLPxHandshake.cpp @@ -172,7 +172,7 @@ void RLPXHandshake::transition(boost::system::error_code _ech) // 5 arguments, HelloPacket RLPStream s; s.append((unsigned)0).appendList(5) - << m_host->protocolVersion() + << dev::p2p::c_protocolVersion << m_host->m_clientVersion << m_host->caps() << m_host->listenPort() diff --git a/test/peer.cpp b/test/peer.cpp index 3ad2e2946..ba8fb0b6e 100644 --- a/test/peer.cpp +++ b/test/peer.cpp @@ -90,7 +90,7 @@ BOOST_AUTO_TEST_CASE(save_nodes) RLP r(firstHostNetwork); BOOST_REQUIRE(r.itemCount() == 3); - BOOST_REQUIRE(r[0].toInt() == NodeTable::c_version); + BOOST_REQUIRE(r[0].toInt() == dev::p2p::c_protocolVersion); BOOST_REQUIRE_EQUAL(r[1].toBytes().size(), 32); // secret BOOST_REQUIRE_EQUAL(r[2].itemCount(), 5); } From 60931709905a582d60ce23792b907b827ad2f6ad Mon Sep 17 00:00:00 2001 From: subtly Date: Sun, 22 Mar 2015 20:18:08 +0100 Subject: [PATCH 36/66] consistent and explicit use of constant for devp2p protocol version --- libp2p/Host.cpp | 4 ++-- libp2p/NodeTable.cpp | 2 +- libp2p/NodeTable.h | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/libp2p/Host.cpp b/libp2p/Host.cpp index 30cadb515..13ea87ba6 100644 --- a/libp2p/Host.cpp +++ b/libp2p/Host.cpp @@ -709,7 +709,7 @@ bytes Host::saveNetwork() const } RLPStream ret(3); - ret << c_protocolVersion << m_alias.secret(); + ret << dev::p2p::c_protocolVersion << m_alias.secret(); ret.appendList(count).appendRaw(network.out(), count); return ret.out(); } @@ -722,7 +722,7 @@ void Host::restoreNetwork(bytesConstRef _b) RecursiveGuard l(x_sessions); RLP r(_b); - if (r.itemCount() > 0 && r[0].isInt() && r[0].toInt() == c_protocolVersion) + if (r.itemCount() > 0 && r[0].isInt() && r[0].toInt() == dev::p2p::c_protocolVersion) { // r[0] = version // r[1] = key diff --git a/libp2p/NodeTable.cpp b/libp2p/NodeTable.cpp index 1f024a911..0d6dda214 100644 --- a/libp2p/NodeTable.cpp +++ b/libp2p/NodeTable.cpp @@ -477,7 +477,7 @@ void NodeTable::onReceived(UDPSocketFace*, bi::udp::endpoint const& _from, bytes case PingNode::type: { PingNode in = PingNode::fromBytesConstRef(_from, rlpBytes); - if (in.version != c_protocolVersion) + if (in.version != dev::p2p::c_protocolVersion) { if (auto n = nodeEntry(nodeid)) dropNode(n); diff --git a/libp2p/NodeTable.h b/libp2p/NodeTable.h index 10ba232c3..58fa722c1 100644 --- a/libp2p/NodeTable.h +++ b/libp2p/NodeTable.h @@ -316,7 +316,7 @@ struct PingNode: RLPXDatagram static const uint8_t type = 1; - unsigned version = c_protocolVersion; + unsigned version = dev::p2p::c_protocolVersion; std::string ipAddress; unsigned port; unsigned expiration; From cddb2920a97db9a80bcb724e55e9bf5e7fe89166 Mon Sep 17 00:00:00 2001 From: subtly Date: Sun, 22 Mar 2015 20:38:27 +0100 Subject: [PATCH 37/66] namespace eth network-protocol version for implemenations --- alethzero/MainWin.cpp | 4 ++-- eth/main.cpp | 2 +- libethereum/Client.cpp | 4 ++-- libethereum/State.cpp | 2 +- neth/main.cpp | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/alethzero/MainWin.cpp b/alethzero/MainWin.cpp index dfd439816..d5e81a4f5 100644 --- a/alethzero/MainWin.cpp +++ b/alethzero/MainWin.cpp @@ -145,7 +145,7 @@ Main::Main(QWidget *parent) : cerr << "Block Hash: " << CanonBlockChain::genesis().hash << endl; cerr << "Block RLP: " << RLP(block) << endl; cerr << "Block Hex: " << toHex(block) << endl; - cerr << "Network protocol version: " << c_protocolVersion << endl; + cerr << "eth Network protocol version: " << eth::c_protocolVersion << endl; cerr << "Client database version: " << c_databaseVersion << endl; ui->configDock->close(); @@ -1059,7 +1059,7 @@ void Main::refreshBlockCount() { cwatch << "refreshBlockCount()"; auto d = ethereum()->blockChain().details(); - ui->blockCount->setText(QString("%4 #%1 PV%2 D%3 H%5").arg(d.number).arg(c_protocolVersion).arg(c_databaseVersion).arg(m_privateChain.size() ? "[" + m_privateChain + "] " : "testnet").arg(c_ethashVersion)); + ui->blockCount->setText(QString("%4 #%1 PV%2 D%3 H%5").arg(d.number).arg(eth::c_protocolVersion).arg(c_databaseVersion).arg(m_privateChain.size() ? "[" + m_privateChain + "] " : "testnet").arg(c_ethashVersion)); } void Main::on_turboMining_triggered() diff --git a/eth/main.cpp b/eth/main.cpp index ce89e8ddf..eda6e12ae 100644 --- a/eth/main.cpp +++ b/eth/main.cpp @@ -160,7 +160,7 @@ string credits(bool _interactive = false) void version() { cout << "eth version " << dev::Version << endl; - cout << "Network protocol version: " << dev::eth::c_protocolVersion << endl; + cout << "eth network protocol version: " << dev::eth::c_protocolVersion << endl; cout << "Client database version: " << dev::eth::c_databaseVersion << endl; cout << "Build: " << DEV_QUOTED(ETH_BUILD_PLATFORM) << "/" << DEV_QUOTED(ETH_BUILD_TYPE) << endl; exit(0); diff --git a/libethereum/Client.cpp b/libethereum/Client.cpp index 6725d1560..883b7f615 100644 --- a/libethereum/Client.cpp +++ b/libethereum/Client.cpp @@ -40,7 +40,7 @@ VersionChecker::VersionChecker(string const& _dbPath): { auto protocolContents = contents(m_path + "/protocol"); auto databaseContents = contents(m_path + "/database"); - m_ok = RLP(protocolContents).toInt(RLP::LaisezFaire) == c_protocolVersion && RLP(databaseContents).toInt(RLP::LaisezFaire) == c_databaseVersion; + m_ok = RLP(protocolContents).toInt(RLP::LaisezFaire) == eth::c_protocolVersion && RLP(databaseContents).toInt(RLP::LaisezFaire) == c_databaseVersion; } void VersionChecker::setOk() @@ -55,7 +55,7 @@ void VersionChecker::setOk() { cwarn << "Unhandled exception! Failed to create directory: " << m_path << "\n" << boost::current_exception_diagnostic_information(); } - writeFile(m_path + "/protocol", rlp(c_protocolVersion)); + writeFile(m_path + "/protocol", rlp(eth::c_protocolVersion)); writeFile(m_path + "/database", rlp(c_databaseVersion)); } } diff --git a/libethereum/State.cpp b/libethereum/State.cpp index 0d2b3a93e..c5732116d 100644 --- a/libethereum/State.cpp +++ b/libethereum/State.cpp @@ -1040,7 +1040,7 @@ LastHashes State::getLastHashes(BlockChain const& _bc, unsigned _n) const { LastHashes ret; ret.resize(256); - if (c_protocolVersion > 49) + if (eth::c_protocolVersion > 49) { ret[0] = _bc.numberHash(_n); for (unsigned i = 1; i < 256; ++i) diff --git a/neth/main.cpp b/neth/main.cpp index 275ac3ea4..9ea28a83e 100644 --- a/neth/main.cpp +++ b/neth/main.cpp @@ -134,7 +134,7 @@ string credits() void version() { cout << "neth version " << dev::Version << endl; - cout << "Network protocol version: " << dev::eth::c_protocolVersion << endl; + cout << "eth network protocol version: " << dev::eth::c_protocolVersion << endl; cout << "Client database version: " << dev::eth::c_databaseVersion << endl; cout << "Build: " << DEV_QUOTED(ETH_BUILD_PLATFORM) << "/" << DEV_QUOTED(ETH_BUILD_TYPE) << endl; exit(0); From 7738cb7d4f49fa22aecc52162d557823b7108f4f Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Sun, 22 Mar 2015 21:42:14 +0100 Subject: [PATCH 38/66] Vastly cleaner Transact dialog code & mechanisms. Works better for lower balances. --- alethzero/Transact.cpp | 386 +++++++++++++++++++++-------------------- alethzero/Transact.h | 2 +- 2 files changed, 196 insertions(+), 192 deletions(-) diff --git a/alethzero/Transact.cpp b/alethzero/Transact.cpp index c9cd5e7b4..7248ee4a6 100644 --- a/alethzero/Transact.cpp +++ b/alethzero/Transact.cpp @@ -25,6 +25,7 @@ #include "Transact.h" #include +#include #include #include #include @@ -135,21 +136,6 @@ void Transact::updateFee() ui->total->setPalette(p); } -string Transact::getFunctionHashes(dev::solidity::CompilerStack const& _compiler, string const& _contractName) -{ - string ret = ""; - auto const& contract = _compiler.getContractDefinition(_contractName); - auto interfaceFunctions = contract.getInterfaceFunctions(); - - for (auto const& it: interfaceFunctions) - { - ret += it.first.abridged(); - ret += " :"; - ret += it.second->getDeclaration().getName() + "\n"; - } - return ret; -} - void Transact::on_destination_currentTextChanged(QString) { if (ui->destination->currentText().size() && ui->destination->currentText() != "(Create Contract)") @@ -182,202 +168,222 @@ static std::string toString(TransactionException _te) } } -void Transact::rejigData() +static string getFunctionHashes(dev::solidity::CompilerStack const& _compiler, string const& _contractName) { - if (!ethereum()) - return; - m_allGood = true; - if (isCreation()) + string ret = ""; + auto const& contract = _compiler.getContractDefinition(_contractName); + auto interfaceFunctions = contract.getInterfaceFunctions(); + + for (auto const& it: interfaceFunctions) { - string src = ui->data->toPlainText().toStdString(); - vector errors; - QString lll; - QString solidity; - if (src.find_first_not_of("1234567890abcdefABCDEF") == string::npos && src.size() % 2 == 0) - m_data = fromHex(src); - else if (sourceIsSolidity(src)) + ret += it.first.abridged(); + ret += " :"; + ret += it.second->getDeclaration().getName() + "\n"; + } + return ret; +} + +static tuple, bytes, string> userInputToCode(string const& _user, bool _opt) +{ + string lll; + string solidity; + bytes data; + vector errors; + if (_user.find_first_not_of("1234567890abcdefABCDEF\n\t ") == string::npos && _user.size() % 2 == 0) + { + std::string u = _user; + boost::replace_all_copy(u, "\n", ""); + boost::replace_all_copy(u, "\t", ""); + boost::replace_all_copy(u, " ", ""); + data = fromHex(u); + } + else if (sourceIsSolidity(_user)) + { + dev::solidity::CompilerStack compiler(true); + try { - dev::solidity::CompilerStack compiler(true); - try - { // compiler.addSources(dev::solidity::StandardSources); - m_data = compiler.compile(src, ui->optimize->isChecked()); - solidity = "

Solidity

"; - solidity += "
var " + QString::fromStdString(compiler.defaultContractName()) + " = web3.eth.contractFromAbi(" + QString::fromStdString(compiler.getInterface()).replace(QRegExp("\\s"), "").toHtmlEscaped() + ");
"; - solidity += "
" + QString::fromStdString(compiler.getSolidityInterface()).toHtmlEscaped() + "
"; - solidity += "
" + QString::fromStdString(getFunctionHashes(compiler)).toHtmlEscaped() + "
"; - } - catch (dev::Exception const& exception) - { - ostringstream error; - solidity::SourceReferenceFormatter::printExceptionInformation(error, exception, "Error", compiler); - errors.push_back("Solidity: " + error.str()); - } - catch (...) - { - errors.push_back("Solidity: Uncaught exception"); - } + data = compiler.compile(_user, _opt); + solidity = "

Solidity

"; + solidity += "
var " + compiler.defaultContractName() + " = web3.eth.contract(" + QString::fromStdString(compiler.getInterface()).replace(QRegExp("\\s"), "").toHtmlEscaped().toStdString() + ");
"; + solidity += "
" + QString::fromStdString(compiler.getSolidityInterface()).toHtmlEscaped().toStdString() + "
"; + solidity += "
" + QString::fromStdString(getFunctionHashes(compiler, "")).toHtmlEscaped().toStdString() + "
"; } + catch (dev::Exception const& exception) + { + ostringstream error; + solidity::SourceReferenceFormatter::printExceptionInformation(error, exception, "Error", compiler); + errors.push_back("Solidity: " + error.str()); + } + catch (...) + { + errors.push_back("Solidity: Uncaught exception"); + } + } #ifndef _MSC_VER - else if (sourceIsSerpent(src)) + else if (sourceIsSerpent(_user)) + { + try { - try - { - m_data = dev::asBytes(::compile(src)); - } - catch (string const& err) - { - errors.push_back("Serpent " + err); - } + data = dev::asBytes(::compile(_user)); } -#endif - else + catch (string const& err) { - m_data = compileLLL(src, ui->optimize->isChecked(), &errors); - if (errors.empty()) - { - auto asmcode = compileLLLToAsm(src, ui->optimize->isChecked()); - lll = "

LLL

" + QString::fromStdString(asmcode).toHtmlEscaped() + "
"; - } + errors.push_back("Serpent " + err); } - QString htmlErrors; - qint64 gasNeeded = 0; - if (errors.size()) + } +#endif + else + { + data = compileLLL(_user, _opt, &errors); + if (errors.empty()) { - htmlErrors = "

Errors

"; - for (auto const& i: errors) - htmlErrors.append("
" + QString::fromStdString(i).toHtmlEscaped() + "
"); - m_allGood = false; + auto asmcode = compileLLLToAsm(_user, _opt); + lll = "

LLL

" + QString::fromStdString(asmcode).toHtmlEscaped().toStdString() + "
"; } + } + return make_tuple(errors, data, lll + solidity); +} + +string Transact::natspecNotice(Address _to, bytes const& _data) +{ + if (ethereum()->codeAt(_to, PendingBlock).size()) + { + string userNotice = m_natSpecDB->getUserNotice(ethereum()->postState().codeHash(_to), _data); + if (userNotice.empty()) + return "Destination contract unknown."; else { - if (true) - { - auto s = findSecret(value() + ethereum()->gasLimitRemaining() * gasPrice()); - if (!s) - htmlErrors += "
WARNING No single account contains a comfortable amount of gas.
"; - // TODO: use account with most balance anyway. - else - { - ExecutionResult er = ethereum()->create(s, value(), m_data, ethereum()->gasLimitRemaining(), gasPrice()); - gasNeeded = (qint64)er.gasUsed; - auto base = (qint64)Interface::txGas(m_data, 0); - htmlErrors += QString("
INFO Gas required: %1 base, %2 init
").arg(base).arg((qint64)er.gasUsed - base); - - if (er.excepted != TransactionException::None) - { - htmlErrors += "
ERROR " + QString::fromStdString(toString(er.excepted)) + "
"; - m_allGood = false; - } - if (er.codeDeposit == CodeDeposit::Failed) - { - htmlErrors += "
ERROR Code deposit failed due to insufficient gas
"; - m_allGood = false; - } - } - } - else - gasNeeded = (qint64)Interface::txGas(m_data, 0); + NatspecExpressionEvaluator evaluator; + return evaluator.evalExpression(QString::fromStdString(userNotice)).toStdString(); } + } + else + return "Destination not a contract."; +} + +void Transact::rejigData() +{ + if (!ethereum()) + return; - ui->code->setHtml(htmlErrors + lll + solidity + "

Code

" + QString::fromStdString(disassemble(m_data)).toHtmlEscaped() + "

Hex

" Div(Mono) + QString::fromStdString(toHex(m_data)) + ""); + // Determine how much balance we have to play with... + auto s = findSecret(value() + ethereum()->gasLimitRemaining() * gasPrice()); + auto b = ethereum()->balanceAt(KeyPair(s).address(), PendingBlock); + + m_allGood = true; + QString htmlInfo; - if (ui->gas->value() == ui->gas->minimum()) + auto bail = [&](QString he) { + m_allGood = false; + ui->send->setEnabled(false); + ui->code->setHtml(he + htmlInfo); + }; + + // Determine m_info. + if (isCreation()) + { + string info; + vector errors; + tie(errors, m_data, info) = userInputToCode(ui->data->toPlainText().toStdString(), ui->optimize->isChecked()); + if (errors.size()) { - ui->gas->setMinimum(gasNeeded); - ui->gas->setValue(gasNeeded); + // Errors determining transaction data (i.e. init code). Bail. + QString htmlErrors; + for (auto const& i: errors) + htmlErrors.append("
ERROR " + QString::fromStdString(i).toHtmlEscaped() + "
"); + bail(htmlErrors); + return; } - else - ui->gas->setMinimum(gasNeeded); -// if (!ui->gas->isEnabled()) -// ui->gas->setValue(m_backupGas); - ui->gas->setEnabled(true); -// if (ui->gas->value() == ui->gas->minimum() && !src.empty()) -// ui->gas->setValue((int)(m_ethereum->postState().gasLimitRemaining() / 10)); + htmlInfo = QString::fromStdString(info) + "

Code

" + QString::fromStdString(disassemble(m_data)).toHtmlEscaped(); } else { - m_allGood = true; - auto base = (qint64)Interface::txGas(m_data, 0); m_data = parseData(ui->data->toPlainText().toStdString()); - auto to = m_context->fromString(ui->destination->currentText()); - QString natspec; - QString errs; - if (ethereum()->codeAt(to, PendingBlock).size()) - { - string userNotice = m_natSpecDB->getUserNotice(ethereum()->postState().codeHash(to), m_data); - if (userNotice.empty()) - natspec = "Destination contract unknown."; - else - { - NatspecExpressionEvaluator evaluator; - natspec = evaluator.evalExpression(QString::fromStdString(userNotice)); - } + htmlInfo = "

Dump

" + QString::fromStdString(dev::memDump(m_data, 8, true)); + } - qint64 gasNeeded = 0; - if (true) - { - auto s = findSecret(value() + ethereum()->gasLimitRemaining() * gasPrice()); - if (!s) - errs += "
ERROR No single account contains enough gas.
"; - // TODO: use account with most balance anyway. - else - { - ExecutionResult er = ethereum()->call(s, value(), to, m_data, ethereum()->gasLimitRemaining(), gasPrice()); - gasNeeded = (qint64)er.gasUsed; - errs += QString("
INFO Gas required: %1 base, %2 exec
").arg(base).arg((qint64)er.gasUsed - base); - - if (er.excepted != TransactionException::None) - { - errs += "
ERROR " + QString::fromStdString(toString(er.excepted)) + "
"; - m_allGood = false; - } - } - } - else - gasNeeded = (qint64)Interface::txGas(m_data, 0); + htmlInfo += "

Hex

" + QString(Div(Mono)) + QString::fromStdString(toHex(m_data)) + ""; - if (ui->gas->value() == ui->gas->minimum()) - { - ui->gas->setMinimum(gasNeeded); - ui->gas->setValue(gasNeeded); - } - else - ui->gas->setMinimum(gasNeeded); + // Determine the minimum amount of gas we need to play... + qint64 baseGas = (qint64)Interface::txGas(m_data, 0); + qint64 gasNeeded = 0; - if (!ui->gas->isEnabled()) - ui->gas->setValue(m_backupGas); - ui->gas->setEnabled(true); - } - else - { - natspec += "Destination not a contract."; - if (ui->gas->isEnabled()) - m_backupGas = ui->gas->value(); - ui->gas->setMinimum(base); - ui->gas->setValue(base); - ui->gas->setEnabled(false); - } - ui->code->setHtml(errs + "

NatSpec

" + natspec + "

Dump

" + QString::fromStdString(dev::memDump(m_data, 8, true)) + "

Hex

" + Div(Mono) + QString::fromStdString(toHex(m_data)) + ""); + if (b < value() + baseGas * gasPrice()) + { + // Not enough - bail. + bail("
ERROR No single account contains enough for paying even the basic amount of gas required.
"); + return; + } + else + gasNeeded = min((qint64)ethereum()->gasLimitRemaining(), (qint64)((b - value()) / gasPrice())); + + // Dry-run execution to determine gas requirement and any execution errors + Address to; + ExecutionResult er; + if (isCreation()) + er = ethereum()->create(s, value(), m_data, gasNeeded, gasPrice()); + else + { + to = m_context->fromString(ui->destination->currentText()); + er = ethereum()->call(s, value(), to, m_data, ethereum()->gasLimitRemaining(), gasPrice()); + } + gasNeeded = (qint64)er.gasUsed; + htmlInfo = QString("
INFO Gas required: %1 total = %2 base, %3 exec
").arg(gasNeeded).arg(baseGas).arg(gasNeeded - baseGas) + htmlInfo; + + if (er.excepted != TransactionException::None) + { + bail("
ERROR " + QString::fromStdString(toString(er.excepted)) + "
"); + return; } + if (er.codeDeposit == CodeDeposit::Failed) + { + bail("
ERROR Code deposit failed due to insufficient gas
"); + return; + } + + // Add Natspec information + if (!isCreation()) + htmlInfo = "
INFO " + QString::fromStdString(natspecNotice(to, m_data)).toHtmlEscaped() + "
" + htmlInfo; + + // Update gas + if (ui->gas->value() == ui->gas->minimum()) + { + ui->gas->setMinimum(gasNeeded); + ui->gas->setValue(gasNeeded); + } + else + ui->gas->setMinimum(gasNeeded); + updateFee(); + ui->code->setHtml(htmlInfo); ui->send->setEnabled(m_allGood); } Secret Transact::findSecret(u256 _totalReq) const { - if (ethereum()) - for (auto const& i: m_myKeys) - if (ethereum()->balanceAt(i.address(), PendingBlock) >= _totalReq) - return i.secret(); - return Secret(); + if (!ethereum()) + return Secret(); + + Secret best; + u256 bestBalance = 0; + for (auto const& i: m_myKeys) + { + auto b = ethereum()->balanceAt(i.address(), PendingBlock); + if (b >= _totalReq) + return i.secret(); + if (b > bestBalance) + bestBalance = b, best = i.secret(); + } + return best; } void Transact::on_send_clicked() { Secret s = findSecret(value() + fee()); - if (!s) + auto b = ethereum()->balanceAt(KeyPair(s).address(), PendingBlock); + if (!s || b < value() + fee()) { QMessageBox::critical(this, "Transaction Failed", "Couldn't make transaction: no single account contains at least the required amount."); return; @@ -400,9 +406,7 @@ void Transact::on_send_clicked() m_natSpecDB->add(contractHash, compiler.getMetadata(s, dev::solidity::DocumentationType::NatspecUser)); } } - catch (...) - { - } + catch (...) {} } else ethereum()->submitTransaction(s, value(), m_context->fromString(ui->destination->currentText()), m_data, ui->gas->value(), gasPrice()); @@ -411,24 +415,24 @@ void Transact::on_send_clicked() void Transact::on_debug_clicked() { + Secret s = findSecret(value() + fee()); + auto b = ethereum()->balanceAt(KeyPair(s).address(), PendingBlock); + if (!s || b < value() + fee()) + { + QMessageBox::critical(this, "Transaction Failed", "Couldn't make transaction: no single account contains at least the required amount."); + return; + } + try { - u256 totalReq = value() + fee(); - for (auto i: m_myKeys) - if (ethereum()->balanceAt(i.address()) >= totalReq) - { - State st(ethereum()->postState()); - Secret s = i.secret(); - Transaction t = isCreation() ? - Transaction(value(), gasPrice(), ui->gas->value(), m_data, st.transactionsFrom(dev::toAddress(s)), s) : - Transaction(value(), gasPrice(), ui->gas->value(), m_context->fromString(ui->destination->currentText()), m_data, st.transactionsFrom(dev::toAddress(s)), s); - Debugger dw(m_context, this); - Executive e(st, ethereum()->blockChain(), 0); - dw.populate(e, t); - dw.exec(); - return; - } - QMessageBox::critical(this, "Transaction Failed", "Couldn't make transaction: no single account contains at least the required amount."); + State st(ethereum()->postState()); + Transaction t = isCreation() ? + Transaction(value(), gasPrice(), ui->gas->value(), m_data, st.transactionsFrom(dev::toAddress(s)), s) : + Transaction(value(), gasPrice(), ui->gas->value(), m_context->fromString(ui->destination->currentText()), m_data, st.transactionsFrom(dev::toAddress(s)), s); + Debugger dw(m_context, this); + Executive e(st, ethereum()->blockChain(), 0); + dw.populate(e, t); + dw.exec(); } catch (dev::Exception const& _e) { diff --git a/alethzero/Transact.h b/alethzero/Transact.h index 0ad9d5653..71bc393b2 100644 --- a/alethzero/Transact.h +++ b/alethzero/Transact.h @@ -68,7 +68,7 @@ private: dev::u256 value() const; dev::u256 gasPrice() const; - std::string getFunctionHashes(dev::solidity::CompilerStack const& _compiler, std::string const& _contractName = std::string()); + std::string natspecNotice(dev::Address _to, dev::bytes const& _data); dev::Secret findSecret(dev::u256 _totalReq) const; Ui::Transact* ui = nullptr; From e01002bef92ba598faf9ece95565891f432ecc8d Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Sun, 22 Mar 2015 22:26:10 +0100 Subject: [PATCH 39/66] Fix signed/unsigned mismatch. --- test/peer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/peer.cpp b/test/peer.cpp index ba8fb0b6e..bfb4680d3 100644 --- a/test/peer.cpp +++ b/test/peer.cpp @@ -90,7 +90,7 @@ BOOST_AUTO_TEST_CASE(save_nodes) RLP r(firstHostNetwork); BOOST_REQUIRE(r.itemCount() == 3); - BOOST_REQUIRE(r[0].toInt() == dev::p2p::c_protocolVersion); + BOOST_REQUIRE(r[0].toInt() == dev::p2p::c_protocolVersion); BOOST_REQUIRE_EQUAL(r[1].toBytes().size(), 32); // secret BOOST_REQUIRE_EQUAL(r[2].itemCount(), 5); } From f64bf8f17a1b4e18441048587a31023d245faf9a Mon Sep 17 00:00:00 2001 From: subtly Date: Sun, 22 Mar 2015 22:37:12 +0100 Subject: [PATCH 40/66] Bug fix. Add destination node to expected discovery ping instead of ourselves. --- libp2p/NodeTable.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libp2p/NodeTable.cpp b/libp2p/NodeTable.cpp index 0d6dda214..ae9e2cdef 100644 --- a/libp2p/NodeTable.cpp +++ b/libp2p/NodeTable.cpp @@ -87,7 +87,8 @@ shared_ptr NodeTable::addNode(Node const& _node) // ping address if nodeid is empty if (!_node.id) { - m_pubkDiscoverPings[m_node.endpoint.udp.address()] = std::chrono::steady_clock::now(); + clog(NodeTableConnect) << "Sending public key discovery Ping to" << _node.endpoint.udp << "(Advertising:" << m_node.endpoint.udp << ")"; + m_pubkDiscoverPings[_node.endpoint.udp.address()] = std::chrono::steady_clock::now(); PingNode p(_node.endpoint.udp, m_node.endpoint.udp.address().to_string(), m_node.endpoint.udp.port()); p.sign(m_secret); m_socketPointer->send(p); From 5c5c01a6e916683b2470055d0492db93ebf9ccdc Mon Sep 17 00:00:00 2001 From: subtly Date: Mon, 23 Mar 2015 00:24:36 +0100 Subject: [PATCH 41/66] fix public-key discovery ping --- libp2p/NodeTable.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libp2p/NodeTable.cpp b/libp2p/NodeTable.cpp index ae9e2cdef..912754c39 100644 --- a/libp2p/NodeTable.cpp +++ b/libp2p/NodeTable.cpp @@ -443,7 +443,10 @@ void NodeTable::onReceived(UDPSocketFace*, bi::udp::endpoint const& _from, bytes n->pending = false; } else if (m_pubkDiscoverPings.count(_from.address())) + { m_pubkDiscoverPings.erase(_from.address()); + addNode(nodeid, _from, bi::tcp::endpoint(_from.address(), _from.port())); + } else return; // unsolicited pong; don't note node as active From 3b0179e4cdc230064e1db0ef676efa4cb0b21075 Mon Sep 17 00:00:00 2001 From: CJentzsch Date: Mon, 23 Mar 2015 10:30:48 +0100 Subject: [PATCH 42/66] stack limit tests --- test/stMemoryTestFiller.json | 204 +++++++++++++++++++++++++++++++++++ 1 file changed, 204 insertions(+) diff --git a/test/stMemoryTestFiller.json b/test/stMemoryTestFiller.json index 676a88feb..9e034f8f3 100644 --- a/test/stMemoryTestFiller.json +++ b/test/stMemoryTestFiller.json @@ -1459,5 +1459,209 @@ "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", "data" : "0xff55883355001144bbccddffeeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" } + }, + + "stackLimitPush32_1024": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "42949672960", + "currentDifficulty" : "256", + "currentTimestamp" : "1", + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "(asm 1021 0x00 MSTORE JUMPDEST 0x0102030405060708090a0102030405060708090a0102030405060708090a0102 0x01 0x00 MLOAD SUB 0x00 MSTORE 0x00 MLOAD 0x06 JUMPI STOP )", + "storage": {} + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "429496729600", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "100000", + "to" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "value" : "10", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + + "stackLimitPush32_1025": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "42949672960", + "currentDifficulty" : "256", + "currentTimestamp" : "1", + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "(asm 1022 0x00 MSTORE JUMPDEST 0x0102030405060708090a0102030405060708090a0102030405060708090a0102 0x01 0x00 MLOAD SUB 0x00 MSTORE 0x00 MLOAD 0x06 JUMPI STOP )", + "storage": {} + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "429496729600", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "100000", + "to" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "value" : "10", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + + "stackLimitPush31_1024": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "42949672960", + "currentDifficulty" : "256", + "currentTimestamp" : "1", + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "(asm 1021 0x00 MSTORE JUMPDEST 0x0102030405060708090a0102030405060708090a0102030405060708090a01 0x01 0x00 MLOAD SUB 0x00 MSTORE 0x00 MLOAD 0x06 JUMPI STOP )", + "storage": {} + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "429496729600", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "100000", + "to" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "value" : "10", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + + "stackLimitPush31_1025": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "42949672960", + "currentDifficulty" : "256", + "currentTimestamp" : "1", + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "(asm 1022 0x00 MSTORE JUMPDEST 0x0102030405060708090a0102030405060708090a0102030405060708090a01 0x01 0x00 MLOAD SUB 0x00 MSTORE 0x00 MLOAD 0x06 JUMPI STOP )", + "storage": {} + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "429496729600", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "100000", + "to" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "value" : "10", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + + "stackLimitGas_1024": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "42949672960", + "currentDifficulty" : "256", + "currentTimestamp" : "1", + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "(asm 1021 0x00 MSTORE JUMPDEST GAS 0x01 0x00 MLOAD SUB 0x00 MSTORE 0x00 MLOAD 0x06 JUMPI STOP )", + "storage": {} + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "429496729600", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "100000", + "to" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "value" : "10", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + + "stackLimitGas_1025": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "42949672960", + "currentDifficulty" : "256", + "currentTimestamp" : "1", + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "(asm 1022 0x00 MSTORE JUMPDEST GAS 0x01 0x00 MLOAD SUB 0x00 MSTORE 0x00 MLOAD 0x06 JUMPI STOP )", + "storage": {} + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "429496729600", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "100000", + "to" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "value" : "10", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } } } From 09c48343d0aa5c4e7ec9ca9ec1908ad25808d561 Mon Sep 17 00:00:00 2001 From: CJentzsch Date: Mon, 23 Mar 2015 10:55:02 +0100 Subject: [PATCH 43/66] memory stress test for memory opdcodes - dejavu issue 28 --- test/stMemoryTestFiller.json | 374 +++++++++++++++++++++++++++++++++++ 1 file changed, 374 insertions(+) diff --git a/test/stMemoryTestFiller.json b/test/stMemoryTestFiller.json index 9e034f8f3..18892774b 100644 --- a/test/stMemoryTestFiller.json +++ b/test/stMemoryTestFiller.json @@ -1663,5 +1663,379 @@ "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", "data" : "" } + }, + + "mstroe8_dejavu": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "42949672960", + "currentDifficulty" : "256", + "currentTimestamp" : "1", + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "0x60F1630FFFFFFF53", + "storage": {} + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "429496729600", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "13421833200", + "to" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "value" : "10", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + + "mload_dejavu": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "42949672960", + "currentDifficulty" : "256", + "currentTimestamp" : "1", + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "0x630FFFFFFF51", + "storage": {} + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "429496729600", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "13421833200", + "to" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "value" : "10", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + + "mstore_dejavu": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "42949672960", + "currentDifficulty" : "256", + "currentTimestamp" : "1", + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "0x60F1630FFFFFFF52", + "storage": {} + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "429496729600", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "13421833200", + "to" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "value" : "10", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + + "log1_dejavu": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "42949672960", + "currentDifficulty" : "256", + "currentTimestamp" : "1", + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "0x60FF60FF630FFFFFFFA1", + "storage": {} + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "429496729600", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "13421833200", + "to" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "value" : "10", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + + "log2_dejavu": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "42949672960", + "currentDifficulty" : "256", + "currentTimestamp" : "1", + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "0x60FF60FF630FFFFFFFA2", + "storage": {} + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "429496729600", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "13421833200", + "to" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "value" : "10", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + + "log3_dejavu": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "42949672960", + "currentDifficulty" : "256", + "currentTimestamp" : "1", + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "0x60FF60FF60FF630FFFFFFFA2", + "storage": {} + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "429496729600", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "13421833200", + "to" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "value" : "10", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + + "log4_dejavu": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "42949672960", + "currentDifficulty" : "256", + "currentTimestamp" : "1", + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "0x60FF60FF60FF630FFFFFFFA2 ", + "storage": {} + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "429496729600", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "13421833200", + "to" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "value" : "10", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + + "extcodecopy_dejavu": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "42949672960", + "currentDifficulty" : "256", + "currentTimestamp" : "1", + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "0x60FF60FF630FFFFFFF630FFFFFFF3C ", + "storage": {} + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "429496729600", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "13421833200", + "to" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "value" : "10", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + + "codecopy_dejavu": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "42949672960", + "currentDifficulty" : "256", + "currentTimestamp" : "1", + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "0x60FF60FF630FFFFFFF630FFFFFFF39 ", + "storage": {} + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "429496729600", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "13421833200", + "to" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "value" : "10", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + + "calldatacopy_dejavu": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "42949672960", + "currentDifficulty" : "256", + "currentTimestamp" : "1", + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "0x60FF60FF630FFFFFFF630FFFFFFF37 ", + "storage": {} + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "429496729600", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "13421833200", + "to" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "value" : "10", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + + "sha3_dejavu": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "42949672960", + "currentDifficulty" : "256", + "currentTimestamp" : "1", + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "0x60FF630FFFFFFF20 ", + "storage": {} + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "429496729600", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "13421833200", + "to" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "value" : "10", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } } } From 2c90ac7261304325714e2f9b22b6f4147665998a Mon Sep 17 00:00:00 2001 From: CJentzsch Date: Mon, 23 Mar 2015 11:03:40 +0100 Subject: [PATCH 44/66] bug fix --- test/stMemoryTestFiller.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/test/stMemoryTestFiller.json b/test/stMemoryTestFiller.json index 18892774b..c92cd9cbc 100644 --- a/test/stMemoryTestFiller.json +++ b/test/stMemoryTestFiller.json @@ -1882,7 +1882,7 @@ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", "nonce" : "0", - "code" : "0x60FF60FF60FF630FFFFFFFA2 ", + "code" : "0x60FF60FF60FF630FFFFFFFA2", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { @@ -1916,7 +1916,7 @@ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", "nonce" : "0", - "code" : "0x60FF60FF630FFFFFFF630FFFFFFF3C ", + "code" : "0x60FF60FF630FFFFFFF630FFFFFFF3C", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { @@ -1950,7 +1950,7 @@ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", "nonce" : "0", - "code" : "0x60FF60FF630FFFFFFF630FFFFFFF39 ", + "code" : "0x60FF60FF630FFFFFFF630FFFFFFF39", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { @@ -1984,7 +1984,7 @@ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", "nonce" : "0", - "code" : "0x60FF60FF630FFFFFFF630FFFFFFF37 ", + "code" : "0x60FF60FF630FFFFFFF630FFFFFFF37", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { @@ -2018,7 +2018,7 @@ "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "balance" : "1000000000000000000", "nonce" : "0", - "code" : "0x60FF630FFFFFFF20 ", + "code" : "0x60FF630FFFFFFF20", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { From 4d7cb406d6d3829717a93e339000d65270ad34dd Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Mon, 23 Mar 2015 11:22:32 +0100 Subject: [PATCH 45/66] Stricter RLP. --- libdevcore/Exceptions.h | 2 ++ libdevcore/RLP.cpp | 31 +++++++++++++++++++++++++------ libdevcore/RLP.h | 34 ++++++++++++++++++---------------- 3 files changed, 45 insertions(+), 22 deletions(-) diff --git a/libdevcore/Exceptions.h b/libdevcore/Exceptions.h index df9f36030..377420003 100644 --- a/libdevcore/Exceptions.h +++ b/libdevcore/Exceptions.h @@ -44,6 +44,8 @@ struct BadHexCharacter: virtual Exception {}; struct RLPException: virtual Exception {}; struct BadCast: virtual RLPException {}; struct BadRLP: virtual RLPException {}; +struct OversizeRLP: virtual RLPException {}; +struct UndersizeRLP: virtual RLPException {}; struct NoNetworking: virtual Exception {}; struct NoUPnPDevice: virtual Exception {}; struct RootNotFound: virtual Exception {}; diff --git a/libdevcore/RLP.cpp b/libdevcore/RLP.cpp index 0dd61b876..26f10ecf5 100644 --- a/libdevcore/RLP.cpp +++ b/libdevcore/RLP.cpp @@ -26,12 +26,31 @@ using namespace dev; bytes dev::RLPNull = rlp(""); bytes dev::RLPEmptyList = rlpList(); +RLP::RLP(bytesConstRef _d, Strictness _s): + m_data(_d) +{ + if ((_s & FailIfTooBig) && actualSize() < _d.size()) + { + if (_s & ThrowOnFail) + BOOST_THROW_EXCEPTION(OversizeRLP()); + else + m_data.reset(); + } + if ((_s & FailIfTooSmall) && actualSize() > _d.size()) + { + if (_s & ThrowOnFail) + BOOST_THROW_EXCEPTION(UndersizeRLP()); + else + m_data.reset(); + } +} + RLP::iterator& RLP::iterator::operator++() { if (m_remaining) { m_lastItem.retarget(m_lastItem.next().data(), m_remaining); - m_lastItem = m_lastItem.cropped(0, RLP(m_lastItem).actualSize()); + m_lastItem = m_lastItem.cropped(0, RLP(m_lastItem, ThrowOnFail | FailIfTooSmall).actualSize()); m_remaining -= std::min(m_remaining, m_lastItem.size()); } else @@ -44,7 +63,7 @@ RLP::iterator::iterator(RLP const& _parent, bool _begin) if (_begin && _parent.isList()) { auto pl = _parent.payload(); - m_lastItem = pl.cropped(0, RLP(pl).actualSize()); + m_lastItem = pl.cropped(0, RLP(pl, ThrowOnFail | FailIfTooSmall).actualSize()); m_remaining = pl.size() - m_lastItem.size(); } else @@ -58,17 +77,17 @@ RLP RLP::operator[](unsigned _i) const { if (_i < m_lastIndex) { - m_lastEnd = RLP(payload()).actualSize(); + m_lastEnd = RLP(payload(), ThrowOnFail | FailIfTooSmall).actualSize(); m_lastItem = payload().cropped(0, m_lastEnd); m_lastIndex = 0; } for (; m_lastIndex < _i && m_lastItem.size(); ++m_lastIndex) { m_lastItem = payload().cropped(m_lastEnd); - m_lastItem = m_lastItem.cropped(0, RLP(m_lastItem).actualSize()); + m_lastItem = m_lastItem.cropped(0, RLP(m_lastItem, ThrowOnFail | FailIfTooSmall).actualSize()); m_lastEnd += m_lastItem.size(); } - return RLP(m_lastItem); + return RLP(m_lastItem, ThrowOnFail | FailIfTooSmall); } RLPs RLP::toList() const @@ -154,7 +173,7 @@ unsigned RLP::items() const bytesConstRef d = payload().cropped(0, length()); unsigned i = 0; for (; d.size(); ++i) - d = d.cropped(RLP(d).actualSize()); + d = d.cropped(RLP(d, ThrowOnFail | FailIfTooSmall).actualSize()); return i; } return 0; diff --git a/libdevcore/RLP.h b/libdevcore/RLP.h index a538fac21..a837f9221 100644 --- a/libdevcore/RLP.h +++ b/libdevcore/RLP.h @@ -62,20 +62,34 @@ static const byte c_rlpListIndLenZero = c_rlpListStart + c_rlpListImmLenCount - class RLP { public: + /// Conversion flags + enum + { + AllowNonCanon = 1, + ThrowOnFail = 4, + FailIfTooBig = 8, + FailIfTooSmall = 16, + Strict = ThrowOnFail | FailIfTooBig, + VeryStrict = ThrowOnFail | FailIfTooBig | FailIfTooSmall, + LaisezFaire = AllowNonCanon + }; + + using Strictness = int; + /// Construct a null node. RLP() {} /// Construct a node of value given in the bytes. - explicit RLP(bytesConstRef _d): m_data(_d) {} + explicit RLP(bytesConstRef _d, Strictness _s = VeryStrict); /// Construct a node of value given in the bytes. - explicit RLP(bytes const& _d): m_data(&_d) {} + explicit RLP(bytes const& _d, Strictness _s = VeryStrict): RLP(&_d, _s) {} /// Construct a node to read RLP data in the bytes given. - RLP(byte const* _b, unsigned _s): m_data(bytesConstRef(_b, _s)) {} + RLP(byte const* _b, unsigned _s, Strictness _st = VeryStrict): RLP(bytesConstRef(_b, _s), _st) {} /// Construct a node to read RLP data in the string. - explicit RLP(std::string const& _s): m_data(bytesConstRef((byte const*)_s.data(), _s.size())) {} + explicit RLP(std::string const& _s, Strictness _st = VeryStrict): RLP(bytesConstRef((byte const*)_s.data(), _s.size()), _st) {} /// The bare data of the RLP. bytesConstRef data() const { return m_data; } @@ -236,18 +250,6 @@ public: return ret; } - /// Int conversion flags - enum - { - AllowNonCanon = 1, - ThrowOnFail = 4, - FailIfTooBig = 8, - FailIfTooSmall = 16, - Strict = ThrowOnFail | FailIfTooBig, - VeryStrict = ThrowOnFail | FailIfTooBig | FailIfTooSmall, - LaisezFaire = AllowNonCanon - }; - /// Converts to int of type given; if isString(), decodes as big-endian bytestream. @returns 0 if not an int or string. template _T toInt(int _flags = Strict) const { From e39ad0d307a3471582557999d731da4742d97773 Mon Sep 17 00:00:00 2001 From: CJentzsch Date: Mon, 23 Mar 2015 13:07:21 +0100 Subject: [PATCH 46/66] gas overflow --- test/vmIOandFlowOperationsTestFiller.json | 28 +++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/test/vmIOandFlowOperationsTestFiller.json b/test/vmIOandFlowOperationsTestFiller.json index 84a5188a6..36e70f684 100644 --- a/test/vmIOandFlowOperationsTestFiller.json +++ b/test/vmIOandFlowOperationsTestFiller.json @@ -3313,6 +3313,34 @@ } }, + "gasOverFlow": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "1000000", + "currentDifficulty" : "256", + "currentTimestamp" : "1", + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "100000000000000000000000", + "nonce" : "0", + "code" : "(asm PUSH1 0x03 JUMPDEST PUSH1 0x01 SAWP1 SUB DUP1 PUSH1 0x02 JUMPI PUSH9 0x010000000000000016 JUMP JUMPDEST PUSH4 0xbadf000d PUSH1 0x11 SSTORE STOP )", + "storage": {} + } + }, + "exec" : { + "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "value" : "1000000000000000000", + "data" : "", + "gasPrice" : "100000000000000", + "gas" : "100000" + } + }, + "byte1": { "env" : { "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", From 9c307fdbcf580d1e2bc41d9b6e8f7b22549d88df Mon Sep 17 00:00:00 2001 From: CJentzsch Date: Mon, 23 Mar 2015 13:08:14 +0100 Subject: [PATCH 47/66] add possibility to have in-chain uncles as tests --- test/blockchain.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/test/blockchain.cpp b/test/blockchain.cpp index 0f5eeaee2..50ca22c54 100644 --- a/test/blockchain.cpp +++ b/test/blockchain.cpp @@ -72,6 +72,7 @@ void doBlockchainTests(json_spirit::mValue& _v, bool _fillin) // create new "genesis" block RLPStream rlpGenesisBlock = createFullBlockFromHeader(biGenesisBlock); biGenesisBlock.verifyInternals(&rlpGenesisBlock.out()); + o["genesisRLP"] = "0x" + toHex(rlpGenesisBlock.out()); // construct blockchain BlockChain bc(rlpGenesisBlock.out(), string(), true); @@ -114,6 +115,15 @@ void doBlockchainTests(json_spirit::mValue& _v, bool _fillin) vBiUncles.push_back(vBiUncles[vBiUncles.size()-1]); continue; } + + if (uncleHeaderObj.count("sameAsBlock")) + { + writeBlockHeaderToJson(uncleHeaderObj_pre, vBiBlocks[(size_t)toInt(uncleHeaderObj["sameAsBlock"])]); + aUncleList.push_back(uncleHeaderObj_pre); + vBiUncles.push_back(vBiBlocks[(size_t)toInt(uncleHeaderObj["sameAsBlock"])]); + continue; + } + BlockInfo uncleBlockFromFields = constructBlock(uncleHeaderObj); // make uncle header valid From 6ef089b1581e79167c1a13f32b41984715838c65 Mon Sep 17 00:00:00 2001 From: CJentzsch Date: Mon, 23 Mar 2015 13:13:35 +0100 Subject: [PATCH 48/66] check overflow for v value in transacition test --- test/ttTransactionTestFiller.json | 60 +++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/test/ttTransactionTestFiller.json b/test/ttTransactionTestFiller.json index 105b64abc..0058feac1 100644 --- a/test/ttTransactionTestFiller.json +++ b/test/ttTransactionTestFiller.json @@ -14,6 +14,66 @@ } }, + "V_overflow32bit" : { + "transaction" : + { + "data" : "0x5544", + "gasLimit" : "2000", + "gasPrice" : "1", + "nonce" : "3", + "to" : "b94f5374fce5edbc8e2a8697c15331677e6ebf0b", + "value" : "10", + "v" : "4294967323", + "r" : "0x98ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4a", + "s" : "0x8887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a3" + } + }, + + "V_overflow32bitSigned" : { + "transaction" : + { + "data" : "0x5544", + "gasLimit" : "2000", + "gasPrice" : "1", + "nonce" : "3", + "to" : "b94f5374fce5edbc8e2a8697c15331677e6ebf0b", + "value" : "10", + "v" : "2147483647", + "r" : "0x98ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4a", + "s" : "0x8887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a3" + } + }, + + "V_overflow64bit" : { + "transaction" : + { + "data" : "0x5544", + "gasLimit" : "2000", + "gasPrice" : "1", + "nonce" : "3", + "to" : "b94f5374fce5edbc8e2a8697c15331677e6ebf0b", + "value" : "10", + "v" : "18446744073709551643", + "r" : "0x98ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4a", + "s" : "0x8887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a3" + } + }, + + "V_overflow64bitSigned" : { + "transaction" : + { + "data" : "0x5544", + "gasLimit" : "2000", + "gasPrice" : "1", + "nonce" : "3", + "to" : "b94f5374fce5edbc8e2a8697c15331677e6ebf0b", + "value" : "10", + "v" : "18446744073709551388", + "r" : "0x98ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4a", + "s" : "0x8887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a3" + } + }, + "WrongVRSTestVEqual26" : { "transaction" : { From bbd6330f040b8f8d80e45178cb4bbcef8338e6f6 Mon Sep 17 00:00:00 2001 From: CJentzsch Date: Mon, 23 Mar 2015 13:14:49 +0100 Subject: [PATCH 49/66] test for in-chain-uncles and uncles with gen 0 --- test/bcUncleTestFiller.json | 189 +++++++++++++++++++++++++++++++++++ test/stMemoryTestFiller.json | 22 ++-- 2 files changed, 200 insertions(+), 11 deletions(-) diff --git a/test/bcUncleTestFiller.json b/test/bcUncleTestFiller.json index 2a2116ea7..5ab4d7957 100644 --- a/test/bcUncleTestFiller.json +++ b/test/bcUncleTestFiller.json @@ -77,6 +77,99 @@ ] }, + "uncleHeaderWithGeneration0" : { + "genesisBlockHeader" : { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "0x8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "131072", + "extraData" : "0x42", + "gasLimit" : "3141592", + "gasUsed" : "0", + "number" : "0", + "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", + "receiptTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot" : "0xf99eb1626cfa6db435c0836235942d7ccaa935f1ae247d3f1c21e495685f903a", + "timestamp" : "0x54c98c81", + "mixHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "nonce" : "0x0102030405060708", + "transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "pre" : { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "10000000000000", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "blocks" : [ + { + "transactions" : [ + { + "data" : "", + "gasLimit" : "314159", + "gasPrice" : "1", + "nonce" : "0", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "10" + } + ], + "uncleHeaders" : [ + ] + }, + { + "transactions" : [ + { + "data" : "", + "gasLimit" : "314159", + "gasPrice" : "1", + "nonce" : "1", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "10" + } + ], + "uncleHeaders" : [ + ] + }, + { + "transactions" : [ + { + "data" : "", + "gasLimit" : "314159", + "gasPrice" : "1", + "nonce" : "2", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "10" + } + ], + "uncleHeaders" : [ + { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "bcde5374fce5edbc8e2a8697c15331677e6ebf0b", + "difficulty" : "131072", + "extraData" : "0x", + "gasLimit" : "3141592", + "gasUsed" : "0", + "hash" : "9de9879b6a81d1b6c4993c63c90a3c9d1e775f14572694778e828bc64972ae04", + "mixHash" : "b557f905d29ed0fca99d65d0adcce698dee97cf72a13c7cd8d7a7826b8eee770", + "nonce" : "18a524c1790fa83b", + "number" : "0", + "parentHash" : "6134fc6b5d99ee03c4aab1592640f6f9dcbc850668d75d631aee34989b938fae", + "receiptTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot" : "ff640b30d613c35dad43e3693329e1b1ee6350f989cf46a288025a1cbfdab9cd", + "timestamp" : "0x54c98c82", + "transactionsTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + } + ] + } + ] + }, + "oneUncle" : { "genesisBlockHeader" : { "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", @@ -170,6 +263,102 @@ ] }, + "InChainUncle" : { + "genesisBlockHeader" : { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "0x8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "131072", + "extraData" : "0x42", + "gasLimit" : "3141592", + "gasUsed" : "0", + "number" : "0", + "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", + "receiptTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot" : "0xf99eb1626cfa6db435c0836235942d7ccaa935f1ae247d3f1c21e495685f903a", + "timestamp" : "0x54c98c81", + "mixHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "nonce" : "0x0102030405060708", + "transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "pre" : { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "10000000000000", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "blocks" : [ + { + "transactions" : [ + { + "data" : "", + "gasLimit" : "314159", + "gasPrice" : "1", + "nonce" : "0", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "10" + } + ], + "uncleHeaders" : [ + ] + }, + { + "transactions" : [ + { + "data" : "", + "gasLimit" : "314159", + "gasPrice" : "1", + "nonce" : "1", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "10" + } + ], + "uncleHeaders" : [ + ] + }, + { + "transactions" : [ + { + "data" : "", + "gasLimit" : "314159", + "gasPrice" : "1", + "nonce" : "2", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "10" + } + ], + "uncleHeaders" : [ + { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "bcde5374fce5edbc8e2a8697c15331677e6ebf0b", + "difficulty" : "131072", + "extraData" : "0x", + "gasLimit" : "3141592", + "gasUsed" : "0", + "hash" : "9de9879b6a81d1b6c4993c63c90a3c9d1e775f14572694778e828bc64972ae04", + "mixHash" : "b557f905d29ed0fca99d65d0adcce698dee97cf72a13c7cd8d7a7826b8eee770", + "nonce" : "18a524c1790fa83b", + "number" : "2", + "parentHash" : "6134fc6b5d99ee03c4aab1592640f6f9dcbc850668d75d631aee34989b938fae", + "receiptTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot" : "ff640b30d613c35dad43e3693329e1b1ee6350f989cf46a288025a1cbfdab9cd", + "timestamp" : "0x54c98c82", + "transactionsTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + { + "sameAsBlock" : "1" + } + ] + } + ] + }, + "twoEqualUncle" : { "genesisBlockHeader" : { "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", diff --git a/test/stMemoryTestFiller.json b/test/stMemoryTestFiller.json index c92cd9cbc..c1754d52f 100644 --- a/test/stMemoryTestFiller.json +++ b/test/stMemoryTestFiller.json @@ -1691,7 +1691,7 @@ "transaction" : { "nonce" : "0", "gasPrice" : "1", - "gasLimit" : "13421833200", + "gasLimit" : "42949672960", "to" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", "value" : "10", "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", @@ -1725,7 +1725,7 @@ "transaction" : { "nonce" : "0", "gasPrice" : "1", - "gasLimit" : "13421833200", + "gasLimit" : "42949672960", "to" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", "value" : "10", "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", @@ -1759,7 +1759,7 @@ "transaction" : { "nonce" : "0", "gasPrice" : "1", - "gasLimit" : "13421833200", + "gasLimit" : "42949672960", "to" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", "value" : "10", "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", @@ -1793,7 +1793,7 @@ "transaction" : { "nonce" : "0", "gasPrice" : "1", - "gasLimit" : "13421833200", + "gasLimit" : "42949672960", "to" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", "value" : "10", "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", @@ -1827,7 +1827,7 @@ "transaction" : { "nonce" : "0", "gasPrice" : "1", - "gasLimit" : "13421833200", + "gasLimit" : "42949672960", "to" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", "value" : "10", "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", @@ -1861,7 +1861,7 @@ "transaction" : { "nonce" : "0", "gasPrice" : "1", - "gasLimit" : "13421833200", + "gasLimit" : "42949672960", "to" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", "value" : "10", "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", @@ -1895,7 +1895,7 @@ "transaction" : { "nonce" : "0", "gasPrice" : "1", - "gasLimit" : "13421833200", + "gasLimit" : "42949672960", "to" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", "value" : "10", "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", @@ -1929,7 +1929,7 @@ "transaction" : { "nonce" : "0", "gasPrice" : "1", - "gasLimit" : "13421833200", + "gasLimit" : "42949672960", "to" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", "value" : "10", "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", @@ -1963,7 +1963,7 @@ "transaction" : { "nonce" : "0", "gasPrice" : "1", - "gasLimit" : "13421833200", + "gasLimit" : "42949672960", "to" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", "value" : "10", "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", @@ -1997,7 +1997,7 @@ "transaction" : { "nonce" : "0", "gasPrice" : "1", - "gasLimit" : "13421833200", + "gasLimit" : "42949672960", "to" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", "value" : "10", "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", @@ -2031,7 +2031,7 @@ "transaction" : { "nonce" : "0", "gasPrice" : "1", - "gasLimit" : "13421833200", + "gasLimit" : "42949672960", "to" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", "value" : "10", "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", From 74335368ff3da5a1bdfd0be51e0b8399e92548eb Mon Sep 17 00:00:00 2001 From: subtly Date: Mon, 23 Mar 2015 14:15:04 +0100 Subject: [PATCH 50/66] add version to packet payload --- libp2p/Host.cpp | 2 +- libp2p/NodeTable.h | 4 ++-- libp2p/RLPxHandshake.cpp | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/libp2p/Host.cpp b/libp2p/Host.cpp index 13ea87ba6..b946d9b3e 100644 --- a/libp2p/Host.cpp +++ b/libp2p/Host.cpp @@ -560,7 +560,7 @@ void Host::run(boost::system::error_code const&) { RecursiveGuard l(x_sessions); for (auto p: m_peers) - if (p.second->shouldReconnect()) + if (p.second->shouldReconnect() && !havePeerSession(p.second->id)) toConnect.push_back(p.second); } diff --git a/libp2p/NodeTable.h b/libp2p/NodeTable.h index 58fa722c1..562942f2f 100644 --- a/libp2p/NodeTable.h +++ b/libp2p/NodeTable.h @@ -321,8 +321,8 @@ struct PingNode: RLPXDatagram unsigned port; unsigned expiration; - void streamRLP(RLPStream& _s) const { _s.appendList(3); _s << ipAddress << port << expiration; } - void interpretRLP(bytesConstRef _bytes) { RLP r(_bytes); ipAddress = r[0].toString(); port = r[1].toInt(); expiration = r[2].toInt(); } + void streamRLP(RLPStream& _s) const { _s.appendList(4); _s << dev::p2p::c_protocolVersion << ipAddress << port << expiration; } + void interpretRLP(bytesConstRef _bytes) { RLP r(_bytes); version = r[0].toInt(); ipAddress = r[1].toString(); port = r[2].toInt(); expiration = r[3].toInt(); } }; /** diff --git a/libp2p/RLPxHandshake.cpp b/libp2p/RLPxHandshake.cpp index 1e42995ee..16bfe0fb1 100644 --- a/libp2p/RLPxHandshake.cpp +++ b/libp2p/RLPxHandshake.cpp @@ -252,7 +252,7 @@ void RLPXHandshake::transition(boost::system::error_code _ech) } clog(NetNote) << (m_originated ? "p2p.connect.egress" : "p2p.connect.ingress") << "hello frame: success. starting session."; - RLP rlp(frame.cropped(1)); + RLP rlp(frame.cropped(1), RLP::ThrowOnFail | RLP::FailIfTooSmall); m_host->startPeerSession(m_remote, rlp, m_io, m_socket->remoteEndpoint()); } }); From 826ebd2a34c51999855b5f2dc6457ff343e24382 Mon Sep 17 00:00:00 2001 From: CJentzsch Date: Mon, 23 Mar 2015 14:41:26 +0100 Subject: [PATCH 51/66] refine bcJS_API_TestFiller.json --- test/bcJS_API_TestFiller.json | 45 +++++++---------------------------- 1 file changed, 9 insertions(+), 36 deletions(-) diff --git a/test/bcJS_API_TestFiller.json b/test/bcJS_API_TestFiller.json index 8c9dbe3ca..468b3b2e8 100644 --- a/test/bcJS_API_TestFiller.json +++ b/test/bcJS_API_TestFiller.json @@ -40,20 +40,11 @@ "blocks" : [ { "transactions" : [ - { - "data" : "", - "gasLimit" : "314159", - "gasPrice" : "1", - "nonce" : "0", - "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", - "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", - "value" : "10" - }, { "data" : "0x60406103ca600439600451602451336000819055506000600481905550816001819055508060028190555042600581905550336003819055505050610381806100496000396000f30060003560e060020a9004806343d726d61461004257806391b7f5ed14610050578063d686f9ee14610061578063f5bade661461006f578063fcfff16f1461008057005b61004a6101de565b60006000f35b61005b6004356100bf565b60006000f35b610069610304565b60006000f35b61007a60043561008e565b60006000f35b6100886100f0565b60006000f35b600054600160a060020a031633600160a060020a031614156100af576100b4565b6100bc565b806001819055505b50565b600054600160a060020a031633600160a060020a031614156100e0576100e5565b6100ed565b806002819055505b50565b600054600160a060020a031633600160a060020a031614806101255750600354600160a060020a031633600160a060020a0316145b61012e57610161565b60016004819055507f59ebeb90bc63057b6515673c3ecf9438e5058bca0f92585014eced636878c9a560006000a16101dc565b60045460011480610173575060015434105b6101b85760016004819055507f59ebeb90bc63057b6515673c3ecf9438e5058bca0f92585014eced636878c9a560006000a142600581905550336003819055506101db565b33600160a060020a03166000346000600060006000848787f16101d757005b5050505b5b565b60006004546000146101ef576101f4565b610301565b600054600160a060020a031633600160a060020a031614801561022c5750600054600160a060020a0316600354600160a060020a0316145b61023557610242565b6000600481905550610301565b600354600160a060020a031633600160a060020a03161461026257610300565b600554420360025402905060015481116102c757600354600160a060020a0316600082600154036000600060006000848787f161029b57005b505050600054600160a060020a03166000826000600060006000848787f16102bf57005b5050506102ee565b600054600160a060020a031660006001546000600060006000848787f16102ea57005b5050505b60006004819055506000546003819055505b5b50565b6000600054600160a060020a031633600160a060020a031614156103275761032c565b61037e565b600554420360025402905060015481116103455761037d565b600054600160a060020a031660006001546000600060006000848787f161036857005b50505060006004819055506000546003819055505b5b505600000000000000000000000000000000000000000000000000000000000000420000000000000000000000000000000000000000000000000000000000000023", "gasLimit" : "600000", "gasPrice" : "1", - "nonce" : "1", + "nonce" : "0", "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", "to" : "", "value" : "100000" @@ -68,7 +59,7 @@ "data" : "", "gasLimit" : "314159", "gasPrice" : "1", - "nonce" : "2", + "nonce" : "1", "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", "value" : "10" @@ -79,20 +70,11 @@ }, { "transactions" : [ - { - "data" : "", - "gasLimit" : "314159", - "gasPrice" : "1", - "nonce" : "3", - "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", - "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", - "value" : "10" - }, { "data" : "0xfcfff16f", "gasLimit" : "600000", "gasPrice" : "1", - "nonce" : "4", + "nonce" : "2", "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", "to" : "6295ee1b4f6dd65047762f924ecd367c17eabf8f", "value" : "0x42" @@ -107,7 +89,7 @@ "data" : "", "gasLimit" : "314159", "gasPrice" : "1", - "nonce" : "5", + "nonce" : "3", "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", "value" : "10" @@ -158,19 +140,10 @@ "data" : "", "gasLimit" : "314159", "gasPrice" : "1", - "nonce" : "6", + "nonce" : "4", "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", "value" : "10" - }, - { - "data" : "0xfcfff16f", - "gasLimit" : "600000", - "gasPrice" : "1", - "nonce" : "0", - "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", - "to" : "6295ee1b4f6dd65047762f924ecd367c17eabf8f", - "value" : "0x42" } ], "uncleHeaders" : [ @@ -182,7 +155,7 @@ "data" : "", "gasLimit" : "314159", "gasPrice" : "1", - "nonce" : "7", + "nonce" : "5", "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", "value" : "10" @@ -215,7 +188,7 @@ "data" : "", "gasLimit" : "314159", "gasPrice" : "1", - "nonce" : "8", + "nonce" : "6", "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", "value" : "10" @@ -230,7 +203,7 @@ "data" : "", "gasLimit" : "314159", "gasPrice" : "1", - "nonce" : "9", + "nonce" : "7", "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", "value" : "10" @@ -245,7 +218,7 @@ "data" : "", "gasLimit" : "314159", "gasPrice" : "1", - "nonce" : "10", + "nonce" : "8", "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", "value" : "10" From 887cdf4bfb584e368ff573ff39e2adc2d531d93b Mon Sep 17 00:00:00 2001 From: subtly Date: Mon, 23 Mar 2015 15:26:48 +0100 Subject: [PATCH 52/66] gracefully handle old pingnode packet --- libp2p/NodeTable.h | 2 +- libp2p/UDP.h | 2 +- test/net.cpp | 11 +++++++++++ 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/libp2p/NodeTable.h b/libp2p/NodeTable.h index 562942f2f..655ce7d43 100644 --- a/libp2p/NodeTable.h +++ b/libp2p/NodeTable.h @@ -316,7 +316,7 @@ struct PingNode: RLPXDatagram static const uint8_t type = 1; - unsigned version = dev::p2p::c_protocolVersion; + unsigned version = 0; std::string ipAddress; unsigned port; unsigned expiration; diff --git a/libp2p/UDP.h b/libp2p/UDP.h index 091f3cc2a..338100c78 100644 --- a/libp2p/UDP.h +++ b/libp2p/UDP.h @@ -77,7 +77,7 @@ template struct RLPXDatagram: public RLPXDatagramFace { RLPXDatagram(bi::udp::endpoint const& _ep): RLPXDatagramFace(_ep) {} - static T fromBytesConstRef(bi::udp::endpoint const& _ep, bytesConstRef _bytes) { T t(_ep); t.interpretRLP(_bytes); return std::move(t); } + static T fromBytesConstRef(bi::udp::endpoint const& _ep, bytesConstRef _bytes) { try { T t(_ep); t.interpretRLP(_bytes); return std::move(t); } catch(...) { T t(_ep); return std::move(t); } } uint8_t packetType() { return T::type; } }; diff --git a/test/net.cpp b/test/net.cpp index 23ad0fb4a..2ecfafb82 100644 --- a/test/net.cpp +++ b/test/net.cpp @@ -145,6 +145,17 @@ public: bool success = false; }; +BOOST_AUTO_TEST_CASE(badPingNodePacket) +{ + // test old versino of pingNode packet w/new + RLPStream s; + s.appendList(3); s << "1.1.1.1" << 30303 << std::chrono::duration_cast((std::chrono::system_clock::now() + chrono::seconds(60)).time_since_epoch()).count(); + + PingNode p((bi::udp::endpoint())); + BOOST_REQUIRE_NO_THROW(p = PingNode::fromBytesConstRef(bi::udp::endpoint(), bytesConstRef(&s.out()))); + BOOST_REQUIRE(p.version = 0); +} + BOOST_AUTO_TEST_CASE(test_neighbours_packet) { KeyPair k = KeyPair::create(); From c63b38e362682fd276d2b9b4d7453d1ddb16dcd7 Mon Sep 17 00:00:00 2001 From: subtly Date: Mon, 23 Mar 2015 15:31:03 +0100 Subject: [PATCH 53/66] fix test typo --- test/net.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/net.cpp b/test/net.cpp index 2ecfafb82..7ba2d8a12 100644 --- a/test/net.cpp +++ b/test/net.cpp @@ -153,7 +153,7 @@ BOOST_AUTO_TEST_CASE(badPingNodePacket) PingNode p((bi::udp::endpoint())); BOOST_REQUIRE_NO_THROW(p = PingNode::fromBytesConstRef(bi::udp::endpoint(), bytesConstRef(&s.out()))); - BOOST_REQUIRE(p.version = 0); + BOOST_REQUIRE(p.version == 0); } BOOST_AUTO_TEST_CASE(test_neighbours_packet) From 22b45721d8c1d91b9431e1761c5105adadb92709 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Mon, 23 Mar 2015 19:22:14 +0100 Subject: [PATCH 54/66] Better NodeTable error detection. --- libp2p/NodeTable.cpp | 26 ++++++++++++++++++++++++++ libp2p/NodeTable.h | 6 ++++-- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/libp2p/NodeTable.cpp b/libp2p/NodeTable.cpp index 912754c39..7fe531762 100644 --- a/libp2p/NodeTable.cpp +++ b/libp2p/NodeTable.cpp @@ -578,3 +578,29 @@ void NodeTable::doRefreshBuckets(boost::system::error_code const& _ec) m_bucketRefreshTimer.async_wait(runcb); } +void PingNode::streamRLP(RLPStream& _s) const +{ + _s.appendList(4); + _s << dev::p2p::c_protocolVersion << ipAddress << port << expiration; +} + +void PingNode::interpretRLP(bytesConstRef _bytes) +{ + RLP r(_bytes); + if (r.itemCountStrict() == 3) + { + version = 2; + ipAddress = r[0].toString(); + port = r[1].toInt(RLP::Strict); + expiration = r[2].toInt(RLP::Strict); + } + else if (r.itemCountStrict() == 4) + { + version = r[0].toInt(RLP::Strict); + ipAddress = r[1].toString(); + port = r[2].toInt(RLP::Strict); + expiration = r[3].toInt(RLP::Strict); + } + else + BOOST_THROW_EXCEPTION(InvalidRLP()); +} diff --git a/libp2p/NodeTable.h b/libp2p/NodeTable.h index 655ce7d43..6a167930d 100644 --- a/libp2p/NodeTable.h +++ b/libp2p/NodeTable.h @@ -288,6 +288,8 @@ inline std::ostream& operator<<(std::ostream& _out, NodeTable const& _nodeTable) return _out; } +struct InvalidRLP: public Exception {}; + /** * Ping packet: Sent to check if node is alive. * PingNode is cached and regenerated after expiration - t, where t is timeout. @@ -321,8 +323,8 @@ struct PingNode: RLPXDatagram unsigned port; unsigned expiration; - void streamRLP(RLPStream& _s) const { _s.appendList(4); _s << dev::p2p::c_protocolVersion << ipAddress << port << expiration; } - void interpretRLP(bytesConstRef _bytes) { RLP r(_bytes); version = r[0].toInt(); ipAddress = r[1].toString(); port = r[2].toInt(); expiration = r[3].toInt(); } + void streamRLP(RLPStream& _s) const override; + void interpretRLP(bytesConstRef _bytes) override; }; /** From e904462675c7dae5eeabd119996f17d824b509f3 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Mon, 23 Mar 2015 19:22:24 +0100 Subject: [PATCH 55/66] Remove numberOf. --- libethereum/Client.cpp | 12 +----------- libethereum/Client.h | 3 --- 2 files changed, 1 insertion(+), 14 deletions(-) diff --git a/libethereum/Client.cpp b/libethereum/Client.cpp index 883b7f615..d2730fb98 100644 --- a/libethereum/Client.cpp +++ b/libethereum/Client.cpp @@ -729,16 +729,6 @@ void Client::doWork() } } -unsigned Client::numberOf(int _n) const -{ - if (_n > 0) - return _n; - else if (_n == GenesisBlock) - return 0; - else - return m_bc.details().number + max(-(int)m_bc.details().number, 1 + _n); -} - State Client::asOf(unsigned _h) const { ReadGuard l(x_stateDB); @@ -747,7 +737,7 @@ State Client::asOf(unsigned _h) const else if (_h == LatestBlock) return m_preMine; else - return State(m_stateDB, m_bc, m_bc.numberHash(numberOf(_h))); + return State(m_stateDB, m_bc, m_bc.numberHash(_h)); } State Client::state(unsigned _txi, h256 _block) const diff --git a/libethereum/Client.h b/libethereum/Client.h index f34eea5bf..6e34dc925 100644 --- a/libethereum/Client.h +++ b/libethereum/Client.h @@ -380,9 +380,6 @@ private: virtual bool turbo() const { return m_turboMining; } virtual bool force() const { return m_forceMining; } - /// Return the actual block number of the block with the given int-number (positive is the same, INT_MIN is genesis block, < 0 is negative age, thus -1 is most recently mined, 0 is pending. - unsigned numberOf(int _b) const; - /// Returns the state object for the full block (i.e. the terminal state) for index _h. /// Works properly with LatestBlock and PendingBlock. State asOf(unsigned _h) const; From e892d9d426a7739f69be2f2e7901204debf6f3ce Mon Sep 17 00:00:00 2001 From: CJentzsch Date: Mon, 23 Mar 2015 20:44:51 +0100 Subject: [PATCH 56/66] style --- test/stMemoryStressTestFiller.json | 1 - test/vmIOandFlowOperationsTestFiller.json | 24 +++++++++++------------ 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/test/stMemoryStressTestFiller.json b/test/stMemoryStressTestFiller.json index 9fff9c0a4..2589191c5 100644 --- a/test/stMemoryStressTestFiller.json +++ b/test/stMemoryStressTestFiller.json @@ -211,5 +211,4 @@ "value" : "264050067" } } - } diff --git a/test/vmIOandFlowOperationsTestFiller.json b/test/vmIOandFlowOperationsTestFiller.json index 36e70f684..01019892f 100644 --- a/test/vmIOandFlowOperationsTestFiller.json +++ b/test/vmIOandFlowOperationsTestFiller.json @@ -3315,20 +3315,20 @@ "gasOverFlow": { "env" : { - "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", - "currentNumber" : "0", - "currentGasLimit" : "1000000", - "currentDifficulty" : "256", - "currentTimestamp" : "1", - "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "1000000", + "currentDifficulty" : "256", + "currentTimestamp" : "1", + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "pre" : { - "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { - "balance" : "100000000000000000000000", - "nonce" : "0", - "code" : "(asm PUSH1 0x03 JUMPDEST PUSH1 0x01 SAWP1 SUB DUP1 PUSH1 0x02 JUMPI PUSH9 0x010000000000000016 JUMP JUMPDEST PUSH4 0xbadf000d PUSH1 0x11 SSTORE STOP )", - "storage": {} - } + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "100000000000000000000000", + "nonce" : "0", + "code" : "(asm PUSH1 0x03 JUMPDEST PUSH1 0x01 SAWP1 SUB DUP1 PUSH1 0x02 JUMPI PUSH9 0x010000000000000016 JUMP JUMPDEST PUSH4 0xbadf000d PUSH1 0x11 SSTORE STOP )", + "storage": {} + } }, "exec" : { "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", From 029b94a6ca5519458fc09098d70559f551327e00 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Mon, 23 Mar 2015 21:08:32 +0100 Subject: [PATCH 57/66] Revert balance transfer on exception. --- libethereum/Executive.cpp | 22 +++++++++++++--------- libethereum/ExtVM.h | 6 +++++- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/libethereum/Executive.cpp b/libethereum/Executive.cpp index b44caf4ee..ddfd20956 100644 --- a/libethereum/Executive.cpp +++ b/libethereum/Executive.cpp @@ -120,9 +120,8 @@ bool Executive::setup() bool Executive::call(Address _receiveAddress, Address _codeAddress, Address _senderAddress, u256 _value, u256 _gasPrice, bytesConstRef _data, u256 _gas, Address _originAddress) { m_isCreation = false; + m_excepted = TransactionException::None; // cnote << "Transferring" << formatBalance(_value) << "to receiver."; - m_s.addBalance(_receiveAddress, _value); - auto it = !(_codeAddress & ~h160(0xffffffff)) ? precompiled().find((unsigned)(u160)_codeAddress) : precompiled().end(); if (it != precompiled().end()) { @@ -147,6 +146,10 @@ bool Executive::call(Address _receiveAddress, Address _codeAddress, Address _sen } else m_endGas = _gas; + + if (m_excepted == TransactionException::None) + m_s.addBalance(_receiveAddress, _value); + return !m_ext; } @@ -158,20 +161,21 @@ bool Executive::create(Address _sender, u256 _endowment, u256 _gasPrice, u256 _g // we delete it explicitly if we decide we need to revert. m_newAddress = right160(sha3(rlpList(_sender, m_s.transactionsFrom(_sender) - 1))); - // Set up new account... + // Execute _init. + if (!_init.empty()) + { + m_vm = VMFactory::create(_gas); + m_ext = make_shared(m_s, m_lastHashes, m_newAddress, _sender, _origin, _endowment, _gasPrice, bytesConstRef(), _init, m_depth); + } + m_s.m_cache[m_newAddress] = Account(m_s.balance(m_newAddress) + _endowment, Account::ContractConception); - // Execute _init. if (_init.empty()) { m_s.m_cache[m_newAddress].setCode({}); m_endGas = _gas; } - else - { - m_vm = VMFactory::create(_gas); - m_ext = make_shared(m_s, m_lastHashes, m_newAddress, _sender, _origin, _endowment, _gasPrice, bytesConstRef(), _init, m_depth); - } + return !m_ext; } diff --git a/libethereum/ExtVM.h b/libethereum/ExtVM.h index d63cd943a..8807bcd58 100644 --- a/libethereum/ExtVM.h +++ b/libethereum/ExtVM.h @@ -82,7 +82,11 @@ public: /// Revert any changes made (by any of the other calls). /// @TODO check call site for the parent manifest being discarded. - virtual void revert() override final { m_s.m_cache = m_origCache; sub.clear(); } + virtual void revert() override final + { + m_s.m_cache = m_origCache; + sub.clear(); + } State& state() const { return m_s; } From 19d09366b05876a2f49a36abc89fc22103f7e06a Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Tue, 24 Mar 2015 08:56:21 +0100 Subject: [PATCH 58/66] Avoid confusing Gustav. --- libethcore/Ethasher.cpp | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/libethcore/Ethasher.cpp b/libethcore/Ethasher.cpp index 44a555fde..1e6f0acef 100644 --- a/libethcore/Ethasher.cpp +++ b/libethcore/Ethasher.cpp @@ -112,15 +112,19 @@ bool Ethasher::verify(BlockInfo const& _header) h256 boundary = u256((bigint(1) << 256) / _header.difficulty); - // should be equivalent to: - auto r = eval(_header); - return r.mixHash == _header.mixHash && r.value <= boundary; - - return ethash_quick_check_difficulty( + bool ret = ethash_quick_check_difficulty( _header.headerHash(WithoutNonce).data(), (uint64_t)(u64)_header.nonce, _header.mixHash.data(), boundary.data()); + +#if ETH_DEBUG + // should be equivalent to: + auto result = eval(_header); + assert((result.mixHash == _header.mixHash && result.value <= boundary) == ret); +#endif + + return ret; } Ethasher::Result Ethasher::eval(BlockInfo const& _header, Nonce const& _nonce) From 59b676b42be803ef01807177a05eebf850ff08ed Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Tue, 24 Mar 2015 08:57:09 +0100 Subject: [PATCH 59/66] Avoid confusing Gustav. --- libethcore/Ethasher.cpp | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/libethcore/Ethasher.cpp b/libethcore/Ethasher.cpp index 44a555fde..1e6f0acef 100644 --- a/libethcore/Ethasher.cpp +++ b/libethcore/Ethasher.cpp @@ -112,15 +112,19 @@ bool Ethasher::verify(BlockInfo const& _header) h256 boundary = u256((bigint(1) << 256) / _header.difficulty); - // should be equivalent to: - auto r = eval(_header); - return r.mixHash == _header.mixHash && r.value <= boundary; - - return ethash_quick_check_difficulty( + bool ret = ethash_quick_check_difficulty( _header.headerHash(WithoutNonce).data(), (uint64_t)(u64)_header.nonce, _header.mixHash.data(), boundary.data()); + +#if ETH_DEBUG + // should be equivalent to: + auto result = eval(_header); + assert((result.mixHash == _header.mixHash && result.value <= boundary) == ret); +#endif + + return ret; } Ethasher::Result Ethasher::eval(BlockInfo const& _header, Nonce const& _nonce) From f3d4351dbfc2b4ea9b7d0db7b3c624262e472442 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Tue, 24 Mar 2015 08:57:45 +0100 Subject: [PATCH 60/66] Make value transfers symmetric. --- libethereum/Executive.cpp | 33 +++++++++++++++++++-------------- libethereum/State.h | 8 ++++++++ libevm/VM.cpp | 6 ------ 3 files changed, 27 insertions(+), 20 deletions(-) diff --git a/libethereum/Executive.cpp b/libethereum/Executive.cpp index ddfd20956..c23047870 100644 --- a/libethereum/Executive.cpp +++ b/libethereum/Executive.cpp @@ -80,27 +80,31 @@ bool Executive::setup() } // Check gas cost is enough. - auto gasCost = Interface::txGas(m_t.data()); + auto gasRequired = Interface::txGas(m_t.data()); - if (m_t.gas() < gasCost) + if (m_t.gas() < gasRequired) { - clog(StateDetail) << "Not enough gas to pay for the transaction: Require >" << gasCost << " Got" << m_t.gas(); - BOOST_THROW_EXCEPTION(OutOfGas() << RequirementError((bigint)gasCost, (bigint)m_t.gas())); + clog(StateDetail) << "Not enough gas to pay for the transaction: Require >" << gasRequired << " Got" << m_t.gas(); + m_excepted = TransactionException::OutOfGas; + BOOST_THROW_EXCEPTION(OutOfGas() << RequirementError((bigint)gasRequired, (bigint)m_t.gas())); } - bigint cost = m_t.value() + (bigint)m_t.gas() * m_t.gasPrice(); + bigint gasCost = (bigint)m_t.gas() * m_t.gasPrice(); + bigint totalCost = m_t.value() + gasCost; // Avoid unaffordable transactions. - if (m_s.balance(m_t.sender()) < cost) + if (m_s.balance(m_t.sender()) < totalCost) { - clog(StateDetail) << "Not enough cash: Require >" << cost << " Got" << m_s.balance(m_t.sender()); - BOOST_THROW_EXCEPTION(NotEnoughCash() << RequirementError(cost, (bigint)m_s.balance(m_t.sender()))); + clog(StateDetail) << "Not enough cash: Require >" << totalCost << " Got" << m_s.balance(m_t.sender()); + m_excepted = TransactionException::NotEnoughCash; + BOOST_THROW_EXCEPTION(NotEnoughCash() << RequirementError(totalCost, (bigint)m_s.balance(m_t.sender()))); } u256 startGasUsed = m_s.gasUsed(); if (startGasUsed + (bigint)m_t.gas() > m_s.m_currentBlock.gasLimit) { clog(StateDetail) << "Too much gas used in this block: Require <" << (m_s.m_currentBlock.gasLimit - startGasUsed) << " Got" << m_t.gas(); + m_excepted = TransactionException::BlockGasLimitReached; BOOST_THROW_EXCEPTION(BlockGasLimitReached() << RequirementError((bigint)(m_s.m_currentBlock.gasLimit - startGasUsed), (bigint)m_t.gas())); } @@ -108,8 +112,8 @@ bool Executive::setup() m_s.noteSending(m_t.sender()); // Pay... - clog(StateDetail) << "Paying" << formatBalance(u256(cost)) << "from sender (includes" << m_t.gas() << "gas at" << formatBalance(m_t.gasPrice()) << ")"; - m_s.subBalance(m_t.sender(), cost); + clog(StateDetail) << "Paying" << formatBalance(u256(gasCost)) << "from sender for gas (" << m_t.gas() << "gas at" << formatBalance(m_t.gasPrice()) << ")"; + m_s.subBalance(m_t.sender(), gasCost); if (m_t.isCreation()) return create(m_t.sender(), m_t.value(), m_t.gasPrice(), m_t.gas() - (u256)gasCost, &m_t.data(), m_t.sender()); @@ -120,7 +124,6 @@ bool Executive::setup() bool Executive::call(Address _receiveAddress, Address _codeAddress, Address _senderAddress, u256 _value, u256 _gasPrice, bytesConstRef _data, u256 _gas, Address _originAddress) { m_isCreation = false; - m_excepted = TransactionException::None; // cnote << "Transferring" << formatBalance(_value) << "to receiver."; auto it = !(_codeAddress & ~h160(0xffffffff)) ? precompiled().find((unsigned)(u160)_codeAddress) : precompiled().end(); if (it != precompiled().end()) @@ -130,6 +133,8 @@ bool Executive::call(Address _receiveAddress, Address _codeAddress, Address _sen { m_endGas = 0; m_excepted = TransactionException::OutOfGasBase; + // Bail from exception. + return true; // true actually means "all finished - nothing more to be done regarding go(). } else { @@ -147,8 +152,7 @@ bool Executive::call(Address _receiveAddress, Address _codeAddress, Address _sen else m_endGas = _gas; - if (m_excepted == TransactionException::None) - m_s.addBalance(_receiveAddress, _value); + m_s.transferBalance(_senderAddress, _receiveAddress, _value); return !m_ext; } @@ -168,7 +172,8 @@ bool Executive::create(Address _sender, u256 _endowment, u256 _gasPrice, u256 _g m_ext = make_shared(m_s, m_lastHashes, m_newAddress, _sender, _origin, _endowment, _gasPrice, bytesConstRef(), _init, m_depth); } - m_s.m_cache[m_newAddress] = Account(m_s.balance(m_newAddress) + _endowment, Account::ContractConception); + m_s.m_cache[m_newAddress] = Account(m_s.balance(m_newAddress), Account::ContractConception); + m_s.transferBalance(_sender, m_newAddress, _endowment); if (_init.empty()) { diff --git a/libethereum/State.h b/libethereum/State.h index 36d3e7c09..46a111a9b 100644 --- a/libethereum/State.h +++ b/libethereum/State.h @@ -219,6 +219,14 @@ public: */ void subBalance(Address _id, bigint _value); + /** + * @brief Transfers "the balance @a _value between two accounts. + * @param _from Account from which @a _value will be deducted. + * @param _to Account to which @a _value will be added. + * @param _value Amount to be transferred. + */ + void transferBalance(Address _from, Address _to, u256 _value) { subBalance(_from, _value); addBalance(_to, _value); } + /// Get the root of the storage of an account. h256 storageRoot(Address _contract) const; diff --git a/libevm/VM.cpp b/libevm/VM.cpp index 2c1627db9..33c943938 100644 --- a/libevm/VM.cpp +++ b/libevm/VM.cpp @@ -614,10 +614,7 @@ bytesConstRef VM::go(ExtVMFace& _ext, OnOpFunc const& _onOp, uint64_t _steps) m_stack.pop_back(); if (_ext.balance(_ext.myAddress) >= endowment && _ext.depth < 1024) - { - _ext.subBalance(endowment); m_stack.push_back((u160)_ext.create(endowment, m_gas, bytesConstRef(m_temp.data() + initOff, initSize), _onOp)); - } else m_stack.push_back(0); break; @@ -644,10 +641,7 @@ bytesConstRef VM::go(ExtVMFace& _ext, OnOpFunc const& _onOp, uint64_t _steps) m_stack.pop_back(); if (_ext.balance(_ext.myAddress) >= value && _ext.depth < 1024) - { - _ext.subBalance(value); m_stack.push_back(_ext.call(inst == Instruction::CALL ? receiveAddress : _ext.myAddress, value, bytesConstRef(m_temp.data() + inOff, inSize), gas, bytesRef(m_temp.data() + outOff, outSize), _onOp, {}, receiveAddress)); - } else m_stack.push_back(0); From 210278dc822276cb3bd2eb37ade1bfee5ce58567 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Tue, 24 Mar 2015 09:17:28 +0100 Subject: [PATCH 61/66] Protocol bump. --- libethcore/Common.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libethcore/Common.cpp b/libethcore/Common.cpp index d26ac0260..d3ecbcc5f 100644 --- a/libethcore/Common.cpp +++ b/libethcore/Common.cpp @@ -34,7 +34,7 @@ namespace eth { const unsigned c_ethashVersion = c_ethashRevision; -const unsigned c_protocolVersion = 58; +const unsigned c_protocolVersion = 59; const unsigned c_databaseBaseVersion = 8; #if ETH_FATDB const unsigned c_databaseVersionModifier = 1; From 43e9fa3afde876fee57f5b3d2d4d37b77b8a6127 Mon Sep 17 00:00:00 2001 From: Jan Willem Penterman Date: Tue, 24 Mar 2015 10:03:20 +0100 Subject: [PATCH 62/66] Win32/MSVC requires ios::binary flag on ofstream to correctly write dag file --- libdevcore/CommonIO.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libdevcore/CommonIO.cpp b/libdevcore/CommonIO.cpp index 4fa132073..46d6e3a6b 100644 --- a/libdevcore/CommonIO.cpp +++ b/libdevcore/CommonIO.cpp @@ -112,6 +112,6 @@ string dev::contentsString(std::string const& _file) void dev::writeFile(std::string const& _file, bytesConstRef _data) { - ofstream(_file, ios::trunc).write((char const*)_data.data(), _data.size()); + ofstream(_file, ios::trunc|ios::binary).write((char const*)_data.data(), _data.size()); } From 386627340f242687d6fa6e55c593f2ccadb1f383 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Tue, 24 Mar 2015 12:06:36 +0100 Subject: [PATCH 63/66] Fixed all around... --- alethzero/MainWin.cpp | 2 +- libethereum/Client.cpp | 1 + libethereum/Executive.cpp | 8 ++++++-- libethereum/Transaction.h | 2 +- 4 files changed, 9 insertions(+), 4 deletions(-) diff --git a/alethzero/MainWin.cpp b/alethzero/MainWin.cpp index d5e81a4f5..d566882f3 100644 --- a/alethzero/MainWin.cpp +++ b/alethzero/MainWin.cpp @@ -907,7 +907,7 @@ void Main::on_nameReg_textChanged() void Main::on_preview_triggered() { - ethereum()->setDefault(ui->preview->isChecked() ? 0 : -1); + ethereum()->setDefault(ui->preview->isChecked() ? PendingBlock : LatestBlock); refreshAll(); } diff --git a/libethereum/Client.cpp b/libethereum/Client.cpp index d2730fb98..9e8a611c6 100644 --- a/libethereum/Client.cpp +++ b/libethereum/Client.cpp @@ -547,6 +547,7 @@ ExecutionResult Client::call(Address _dest, bytes const& _data, u256 _gas, u256 { ReadGuard l(x_stateDB); temp = m_postMine; + temp.addBalance(Address(), _value + _gasPrice * _gas); } Executive e(temp, LastHashes(), 0); if (!e.call(_dest, _dest, Address(), _value, _gasPrice, &_data, _gas, Address())) diff --git a/libethereum/Executive.cpp b/libethereum/Executive.cpp index c23047870..13b6df884 100644 --- a/libethereum/Executive.cpp +++ b/libethereum/Executive.cpp @@ -116,9 +116,9 @@ bool Executive::setup() m_s.subBalance(m_t.sender(), gasCost); if (m_t.isCreation()) - return create(m_t.sender(), m_t.value(), m_t.gasPrice(), m_t.gas() - (u256)gasCost, &m_t.data(), m_t.sender()); + return create(m_t.sender(), m_t.value(), m_t.gasPrice(), m_t.gas() - (u256)gasRequired, &m_t.data(), m_t.sender()); else - return call(m_t.receiveAddress(), m_t.receiveAddress(), m_t.sender(), m_t.value(), m_t.gasPrice(), bytesConstRef(&m_t.data()), m_t.gas() - (u256)gasCost, m_t.sender()); + return call(m_t.receiveAddress(), m_t.receiveAddress(), m_t.sender(), m_t.value(), m_t.gasPrice(), bytesConstRef(&m_t.data()), m_t.gas() - (u256)gasRequired, m_t.sender()); } bool Executive::call(Address _receiveAddress, Address _codeAddress, Address _senderAddress, u256 _value, u256 _gasPrice, bytesConstRef _data, u256 _gas, Address _originAddress) @@ -152,7 +152,11 @@ bool Executive::call(Address _receiveAddress, Address _codeAddress, Address _sen else m_endGas = _gas; + cdebug << m_s; + State prev = m_s; m_s.transferBalance(_senderAddress, _receiveAddress, _value); + cdebug << m_s; + cdebug << m_s.diff(prev); return !m_ext; } diff --git a/libethereum/Transaction.h b/libethereum/Transaction.h index 561ec6269..1287be64e 100644 --- a/libethereum/Transaction.h +++ b/libethereum/Transaction.h @@ -76,7 +76,7 @@ struct ExecutionResult { ExecutionResult() = default; ExecutionResult(u256 _gasUsed, TransactionException _excepted, Address _newAddress, bytesConstRef _output, CodeDeposit _codeDeposit): gasUsed(_gasUsed), excepted(_excepted), newAddress(_newAddress), output(_output.toBytes()), codeDeposit(_codeDeposit) {} - u256 gasUsed; + u256 gasUsed = 0; TransactionException excepted = TransactionException::Unknown; Address newAddress; bytes output; From a48ce877d23bc9f205bfc6fab1567ed211489287 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Tue, 24 Mar 2015 12:07:45 +0100 Subject: [PATCH 64/66] Reduce verbosity. --- libethereum/Executive.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/libethereum/Executive.cpp b/libethereum/Executive.cpp index 13b6df884..597506821 100644 --- a/libethereum/Executive.cpp +++ b/libethereum/Executive.cpp @@ -152,11 +152,7 @@ bool Executive::call(Address _receiveAddress, Address _codeAddress, Address _sen else m_endGas = _gas; - cdebug << m_s; - State prev = m_s; m_s.transferBalance(_senderAddress, _receiveAddress, _value); - cdebug << m_s; - cdebug << m_s.diff(prev); return !m_ext; } From a86fa46e894b2fde39bfefcbda24464917d2db05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Bylica?= Date: Tue, 24 Mar 2015 13:57:03 +0100 Subject: [PATCH 65/66] Do not subbalance twice VM does not need to subbalance a caller. Balance tranfer is taken care on higher level. --- evmjit/libevmjit-cpp/Env.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/evmjit/libevmjit-cpp/Env.cpp b/evmjit/libevmjit-cpp/Env.cpp index fae320c28..b89aca726 100644 --- a/evmjit/libevmjit-cpp/Env.cpp +++ b/evmjit/libevmjit-cpp/Env.cpp @@ -52,7 +52,6 @@ extern "C" auto endowment = llvm2eth(*_endowment); if (_env->balance(_env->myAddress) >= endowment && _env->depth < 1024) { - _env->subBalance(endowment); u256 gas = *io_gas; h256 address(_env->create(endowment, gas, {_initBeg, _initSize}, {}), h256::AlignRight); *io_gas = static_cast(gas); @@ -89,10 +88,7 @@ extern "C" auto ret = false; auto callGas = u256{_callGas}; if (_env->balance(_env->myAddress) >= value && _env->depth < 1024) - { - _env->subBalance(value); ret = _env->call(receiveAddress, value, {_inBeg, _inSize}, callGas, {_outBeg, _outSize}, {}, {}, codeAddress); - } *io_gas += static_cast(callGas); // it is never more than initial _callGas return ret; From 8926a979ed227ca5366b8b32035063994051a54e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Bylica?= Date: Tue, 24 Mar 2015 15:22:29 +0100 Subject: [PATCH 66/66] Select list-burr LLVM instruction scheduler Workaround for LLVM bug https://llvm.org/bugs/show_bug.cgi?id=22304 in source scheduler. --- evmjit/libevmjit/ExecutionEngine.cpp | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/evmjit/libevmjit/ExecutionEngine.cpp b/evmjit/libevmjit/ExecutionEngine.cpp index f9588fbea..c00691f3e 100644 --- a/evmjit/libevmjit/ExecutionEngine.cpp +++ b/evmjit/libevmjit/ExecutionEngine.cpp @@ -4,6 +4,8 @@ #include #include #include +#include +#include #include "preprocessor/llvm_includes_start.h" #include @@ -82,7 +84,19 @@ void parseOptions() { static llvm::llvm_shutdown_obj shutdownObj{}; cl::AddExtraVersionPrinter(printVersion); - cl::ParseEnvironmentOptions("evmjit", "EVMJIT", "Ethereum EVM JIT Compiler"); + //cl::ParseEnvironmentOptions("evmjit", "EVMJIT", "Ethereum EVM JIT Compiler"); + + // FIXME: LLVM workaround: + // Manually select instruction scheduler other than "source". + // "source" scheduler has a bug: http://llvm.org/bugs/show_bug.cgi?id=22304 + auto envLine = std::getenv("EVMJIT"); + auto commandLine = std::string{"evmjit "} + (envLine ? envLine : "") + " -pre-RA-sched=list-burr\0"; + char const* argv[100] = {nullptr, }; + auto arg = std::strtok(&*commandLine.begin(), " "); + auto i = 0; + for (; i < sizeof(argv) / sizeof(argv[0]) && arg; ++i, arg = std::strtok(nullptr, " ")) + argv[i] = arg; + cl::ParseCommandLineOptions(i, argv, "Ethereum EVM JIT Compiler"); } }